From d2185250fd242ad9498d3516985bf0d448dd0eb7 Mon Sep 17 00:00:00 2001 From: lforst <8118419+lforst@users.noreply.github.com> Date: Tue, 20 Oct 2026 10:58:01 +0000 Subject: [PATCH 1/4] feat(cloudflare-think): Support versions 0.13 through 0.20 --- e2e/config/pr-comment-scenarios.json | 216 +- e2e/helpers/pr-e2e-links.test.ts | 35 +- ...udflare-think-v0-13-ai6-auto.cassette.json | 645 ++ ...flare-think-v0-13-ai6-manual.cassette.json | 645 ++ ...-think-v0-13-latest-ai6-auto.cassette.json | 645 ++ ...hink-v0-13-latest-ai6-manual.cassette.json | 645 ++ ...udflare-think-v0-14-ai6-auto.cassette.json | 645 ++ ...flare-think-v0-14-ai6-manual.cassette.json | 645 ++ ...-think-v0-14-latest-ai6-auto.cassette.json | 645 ++ ...hink-v0-14-latest-ai6-manual.cassette.json | 645 ++ ...udflare-think-v0-15-ai6-auto.cassette.json | 645 ++ ...flare-think-v0-15-ai6-manual.cassette.json | 645 ++ ...udflare-think-v0-15-ai7-auto.cassette.json | 645 ++ ...flare-think-v0-15-ai7-manual.cassette.json | 645 ++ ...-think-v0-15-latest-ai6-auto.cassette.json | 645 ++ ...hink-v0-15-latest-ai6-manual.cassette.json | 645 ++ ...-think-v0-15-latest-ai7-auto.cassette.json | 645 ++ ...hink-v0-15-latest-ai7-manual.cassette.json | 645 ++ ...udflare-think-v0-16-ai6-auto.cassette.json | 645 ++ ...flare-think-v0-16-ai6-manual.cassette.json | 645 ++ ...dflare-think-v0-16-ai7-auto.cassette.json} | 82 +- ...flare-think-v0-16-ai7-manual.cassette.json | 645 ++ ...-think-v0-16-latest-ai6-auto.cassette.json | 645 ++ ...hink-v0-16-latest-ai6-manual.cassette.json | 645 ++ ...-think-v0-16-latest-ai7-auto.cassette.json | 645 ++ ...hink-v0-16-latest-ai7-manual.cassette.json | 645 ++ ...dflare-think-v0-17-ai6-auto.cassette.json} | 82 +- ...lare-think-v0-17-ai6-manual.cassette.json} | 82 +- ...udflare-think-v0-17-ai7-auto.cassette.json | 645 ++ ...flare-think-v0-17-ai7-manual.cassette.json | 645 ++ ...-think-v0-17-latest-ai6-auto.cassette.json | 645 ++ ...hink-v0-17-latest-ai6-manual.cassette.json | 645 ++ ...-think-v0-17-latest-ai7-auto.cassette.json | 645 ++ ...hink-v0-17-latest-ai7-manual.cassette.json | 645 ++ ...udflare-think-v0-18-ai6-auto.cassette.json | 645 ++ ...flare-think-v0-18-ai6-manual.cassette.json | 645 ++ ...udflare-think-v0-18-ai7-auto.cassette.json | 645 ++ ...flare-think-v0-18-ai7-manual.cassette.json | 645 ++ ...-think-v0-18-latest-ai6-auto.cassette.json | 645 ++ ...hink-v0-18-latest-ai6-manual.cassette.json | 645 ++ ...-think-v0-18-latest-ai7-auto.cassette.json | 645 ++ ...hink-v0-18-latest-ai7-manual.cassette.json | 645 ++ ...udflare-think-v0-19-ai6-auto.cassette.json | 645 ++ ...flare-think-v0-19-ai6-manual.cassette.json | 645 ++ ...udflare-think-v0-19-ai7-auto.cassette.json | 645 ++ ...flare-think-v0-19-ai7-manual.cassette.json | 645 ++ ...-think-v0-19-latest-ai6-auto.cassette.json | 645 ++ ...hink-v0-19-latest-ai6-manual.cassette.json | 645 ++ ...-think-v0-19-latest-ai7-auto.cassette.json | 645 ++ ...hink-v0-19-latest-ai7-manual.cassette.json | 645 ++ ...flare-think-v0-20-1-ai7-auto.cassette.json | 645 ++ ...re-think-v0-20-1-ai7-manual.cassette.json} | 82 +- ...udflare-think-v0-20-ai7-auto.cassette.json | 645 ++ ...flare-think-v0-20-ai7-manual.cassette.json | 645 ++ ...-think-v0-20-latest-ai7-auto.cassette.json | 645 ++ ...hink-v0-20-latest-ai7-manual.cassette.json | 645 ++ ...dflare-think-v0-13-ai6-auto.span-tree.json | 922 +++ ...udflare-think-v0-13-ai6-auto.span-tree.txt | 902 +++ ...lare-think-v0-13-ai6-manual.span-tree.json | 921 +++ ...flare-think-v0-13-ai6-manual.span-tree.txt | 901 +++ ...think-v0-13-latest-ai6-auto.span-tree.json | 922 +++ ...-think-v0-13-latest-ai6-auto.span-tree.txt | 902 +++ ...ink-v0-13-latest-ai6-manual.span-tree.json | 921 +++ ...hink-v0-13-latest-ai6-manual.span-tree.txt | 901 +++ ...dflare-think-v0-14-ai6-auto.span-tree.json | 922 +++ ...udflare-think-v0-14-ai6-auto.span-tree.txt | 902 +++ ...lare-think-v0-14-ai6-manual.span-tree.json | 921 +++ ...flare-think-v0-14-ai6-manual.span-tree.txt | 901 +++ ...think-v0-14-latest-ai6-auto.span-tree.json | 922 +++ ...-think-v0-14-latest-ai6-auto.span-tree.txt | 902 +++ ...ink-v0-14-latest-ai6-manual.span-tree.json | 921 +++ ...hink-v0-14-latest-ai6-manual.span-tree.txt | 901 +++ ...dflare-think-v0-15-ai6-auto.span-tree.json | 922 +++ ...udflare-think-v0-15-ai6-auto.span-tree.txt | 902 +++ ...lare-think-v0-15-ai6-manual.span-tree.json | 921 +++ ...flare-think-v0-15-ai6-manual.span-tree.txt | 901 +++ ...flare-think-v0-15-ai7-auto.span-tree.json} | 151 +- ...udflare-think-v0-15-ai7-auto.span-tree.txt | 716 +++ ...lare-think-v0-15-ai7-manual.span-tree.json | 919 +++ ...flare-think-v0-15-ai7-manual.span-tree.txt | 899 +++ ...think-v0-15-latest-ai6-auto.span-tree.json | 922 +++ ...-think-v0-15-latest-ai6-auto.span-tree.txt | 902 +++ ...ink-v0-15-latest-ai6-manual.span-tree.json | 921 +++ ...hink-v0-15-latest-ai6-manual.span-tree.txt | 901 +++ ...hink-v0-15-latest-ai7-auto.span-tree.json} | 159 +- ...think-v0-15-latest-ai7-auto.span-tree.txt} | 159 +- ...ink-v0-15-latest-ai7-manual.span-tree.json | 919 +++ ...hink-v0-15-latest-ai7-manual.span-tree.txt | 899 +++ ...dflare-think-v0-16-ai6-auto.span-tree.json | 922 +++ ...udflare-think-v0-16-ai6-auto.span-tree.txt | 902 +++ ...lare-think-v0-16-ai6-manual.span-tree.json | 921 +++ ...flare-think-v0-16-ai6-manual.span-tree.txt | 901 +++ ...flare-think-v0-16-ai7-auto.span-tree.json} | 151 +- ...dflare-think-v0-16-ai7-auto.span-tree.txt} | 151 +- ...lare-think-v0-16-ai7-manual.span-tree.json | 919 +++ ...flare-think-v0-16-ai7-manual.span-tree.txt | 899 +++ ...think-v0-16-latest-ai6-auto.span-tree.json | 922 +++ ...-think-v0-16-latest-ai6-auto.span-tree.txt | 902 +++ ...ink-v0-16-latest-ai6-manual.span-tree.json | 921 +++ ...hink-v0-16-latest-ai6-manual.span-tree.txt | 901 +++ ...think-v0-16-latest-ai7-auto.span-tree.json | 736 +++ ...-think-v0-16-latest-ai7-auto.span-tree.txt | 716 +++ ...ink-v0-16-latest-ai7-manual.span-tree.json | 919 +++ ...hink-v0-16-latest-ai7-manual.span-tree.txt | 899 +++ ...dflare-think-v0-17-ai6-auto.span-tree.json | 922 +++ ...udflare-think-v0-17-ai6-auto.span-tree.txt | 902 +++ ...lare-think-v0-17-ai6-manual.span-tree.json | 921 +++ ...flare-think-v0-17-ai6-manual.span-tree.txt | 901 +++ ...dflare-think-v0-17-ai7-auto.span-tree.json | 736 +++ ...dflare-think-v0-17-ai7-auto.span-tree.txt} | 151 +- ...lare-think-v0-17-ai7-manual.span-tree.json | 919 +++ ...flare-think-v0-17-ai7-manual.span-tree.txt | 899 +++ ...think-v0-17-latest-ai6-auto.span-tree.json | 922 +++ ...-think-v0-17-latest-ai6-auto.span-tree.txt | 902 +++ ...ink-v0-17-latest-ai6-manual.span-tree.json | 921 +++ ...hink-v0-17-latest-ai6-manual.span-tree.txt | 901 +++ ...think-v0-17-latest-ai7-auto.span-tree.json | 736 +++ ...-think-v0-17-latest-ai7-auto.span-tree.txt | 716 +++ ...ink-v0-17-latest-ai7-manual.span-tree.json | 919 +++ ...hink-v0-17-latest-ai7-manual.span-tree.txt | 899 +++ ...dflare-think-v0-18-ai6-auto.span-tree.json | 922 +++ ...udflare-think-v0-18-ai6-auto.span-tree.txt | 902 +++ ...lare-think-v0-18-ai6-manual.span-tree.json | 921 +++ ...flare-think-v0-18-ai6-manual.span-tree.txt | 901 +++ ...flare-think-v0-18-ai7-auto.span-tree.json} | 137 +- ...dflare-think-v0-18-ai7-auto.span-tree.txt} | 137 +- ...lare-think-v0-18-ai7-manual.span-tree.json | 919 +++ ...flare-think-v0-18-ai7-manual.span-tree.txt | 899 +++ ...think-v0-18-latest-ai6-auto.span-tree.json | 922 +++ ...-think-v0-18-latest-ai6-auto.span-tree.txt | 902 +++ ...ink-v0-18-latest-ai6-manual.span-tree.json | 921 +++ ...hink-v0-18-latest-ai6-manual.span-tree.txt | 901 +++ ...think-v0-18-latest-ai7-auto.span-tree.json | 736 +++ ...-think-v0-18-latest-ai7-auto.span-tree.txt | 716 +++ ...ink-v0-18-latest-ai7-manual.span-tree.json | 919 +++ ...hink-v0-18-latest-ai7-manual.span-tree.txt | 899 +++ ...dflare-think-v0-19-ai6-auto.span-tree.json | 922 +++ ...udflare-think-v0-19-ai6-auto.span-tree.txt | 902 +++ ...lare-think-v0-19-ai6-manual.span-tree.json | 921 +++ ...flare-think-v0-19-ai6-manual.span-tree.txt | 901 +++ ...dflare-think-v0-19-ai7-auto.span-tree.json | 736 +++ ...udflare-think-v0-19-ai7-auto.span-tree.txt | 716 +++ ...lare-think-v0-19-ai7-manual.span-tree.json | 919 +++ ...flare-think-v0-19-ai7-manual.span-tree.txt | 899 +++ ...think-v0-19-latest-ai6-auto.span-tree.json | 922 +++ ...-think-v0-19-latest-ai6-auto.span-tree.txt | 902 +++ ...ink-v0-19-latest-ai6-manual.span-tree.json | 921 +++ ...hink-v0-19-latest-ai6-manual.span-tree.txt | 901 +++ ...think-v0-19-latest-ai7-auto.span-tree.json | 736 +++ ...-think-v0-19-latest-ai7-auto.span-tree.txt | 716 +++ ...ink-v0-19-latest-ai7-manual.span-tree.json | 919 +++ ...hink-v0-19-latest-ai7-manual.span-tree.txt | 899 +++ ...lare-think-v0-20-1-ai7-auto.span-tree.json | 736 +++ ...flare-think-v0-20-1-ai7-auto.span-tree.txt | 716 +++ ...re-think-v0-20-1-ai7-manual.span-tree.json | 919 +++ ...are-think-v0-20-1-ai7-manual.span-tree.txt | 899 +++ ...dflare-think-v0-20-ai7-auto.span-tree.json | 736 +++ ...udflare-think-v0-20-ai7-auto.span-tree.txt | 716 +++ ...lare-think-v0-20-ai7-manual.span-tree.json | 919 +++ ...flare-think-v0-20-ai7-manual.span-tree.txt | 899 +++ ...think-v0-20-latest-ai7-auto.span-tree.json | 736 +++ ...-think-v0-20-latest-ai7-auto.span-tree.txt | 716 +++ ...ink-v0-20-latest-ai7-manual.span-tree.json | 919 +++ ...hink-v0-20-latest-ai7-manual.span-tree.txt | 899 +++ .../assertions.ts | 66 +- .../package.json | 115 +- .../pnpm-lock.yaml | 4708 +------------- .../scenario.test.ts | 79 +- .../{ => template}/scenario.ts | 11 +- .../{ => template}/src/worker.ts | 0 .../{ => template}/src/wrapped-ai.ts | 0 .../{ => template}/vite.config.ts | 4 + .../{ => template}/wrangler.jsonc | 0 .../versions/ai6/package.json | 57 + .../versions/ai6/pnpm-lock.yaml | 5655 +++++++++++++++++ .../versions/ai7/package.json | 55 + .../versions/ai7/pnpm-lock.yaml | 5515 ++++++++++++++++ e2e/scripts/build-pr-e2e-links-comment.mjs | 19 +- .../auto-instrumentations/configs/ai-sdk.ts | 11 + .../configs/cloudflare-think.ts | 2 +- .../plugins/ai-sdk-interceptors.ts | 3 + .../instrumentation/plugins/ai-sdk-plugin.ts | 8 +- .../plugins/cloudflare-think-context.ts | 23 +- .../plugins/cloudflare-think-interceptors.ts | 2 +- .../plugins/cloudflare-think-plugin.test.ts | 264 + .../plugins/cloudflare-think-plugin.ts | 67 +- js/src/vendor-sdk-types/ai-sdk-common.ts | 2 + js/src/vendor-sdk-types/cloudflare-think.ts | 1 + js/src/wrappers/ai-sdk/telemetry.ts | 53 +- js/src/wrappers/cloudflare-think.test.ts | 33 + js/src/wrappers/cloudflare-think.ts | 4 +- 191 files changed, 133063 insertions(+), 5465 deletions(-) create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-latest-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-latest-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-manual.cassette.json rename e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/{cloudflare-think-v0-latest-manual.cassette.json => cloudflare-think-v0-16-ai7-auto.cassette.json} (85%) create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-manual.cassette.json rename e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/{cloudflare-think-v0-auto.cassette.json => cloudflare-think-v0-17-ai6-auto.cassette.json} (87%) rename e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/{cloudflare-think-v0-manual.cassette.json => cloudflare-think-v0-17-ai6-manual.cassette.json} (87%) create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-1-ai7-auto.cassette.json rename e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/{cloudflare-think-v0-latest-auto.cassette.json => cloudflare-think-v0-20-1-ai7-manual.cassette.json} (88%) create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-ai7-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-ai7-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-latest-ai7-auto.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-latest-ai7-manual.cassette.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.txt rename e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/{cloudflare-think-v0-manual.span-tree.json => cloudflare-think-v0-15-ai7-auto.span-tree.json} (82%) create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.txt rename e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/{cloudflare-think-v0-auto.span-tree.json => cloudflare-think-v0-15-latest-ai7-auto.span-tree.json} (82%) rename e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/{cloudflare-think-v0-auto.span-tree.txt => cloudflare-think-v0-15-latest-ai7-auto.span-tree.txt} (81%) create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.txt rename e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/{cloudflare-think-v0-latest-manual.span-tree.json => cloudflare-think-v0-16-ai7-auto.span-tree.json} (82%) rename e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/{cloudflare-think-v0-latest-manual.span-tree.txt => cloudflare-think-v0-16-ai7-auto.span-tree.txt} (82%) create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.json rename e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/{cloudflare-think-v0-manual.span-tree.txt => cloudflare-think-v0-17-ai7-auto.span-tree.txt} (82%) create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.txt rename e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/{cloudflare-think-v0-latest-auto.span-tree.json => cloudflare-think-v0-18-ai7-auto.span-tree.json} (83%) rename e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/{cloudflare-think-v0-latest-auto.span-tree.txt => cloudflare-think-v0-18-ai7-auto.span-tree.txt} (83%) create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-manual.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-auto.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-auto.span-tree.txt create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-manual.span-tree.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-manual.span-tree.txt rename e2e/scenarios/cloudflare-think-instrumentation/{ => template}/scenario.ts (89%) rename e2e/scenarios/cloudflare-think-instrumentation/{ => template}/src/worker.ts (100%) rename e2e/scenarios/cloudflare-think-instrumentation/{ => template}/src/wrapped-ai.ts (100%) rename e2e/scenarios/cloudflare-think-instrumentation/{ => template}/vite.config.ts (81%) rename e2e/scenarios/cloudflare-think-instrumentation/{ => template}/wrangler.jsonc (100%) create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/package.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/pnpm-lock.yaml create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/package.json create mode 100644 e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/pnpm-lock.yaml diff --git a/e2e/config/pr-comment-scenarios.json b/e2e/config/pr-comment-scenarios.json index f6a06afae..864bcc8df 100644 --- a/e2e/config/pr-comment-scenarios.json +++ b/e2e/config/pr-comment-scenarios.json @@ -155,12 +155,220 @@ "metadataScenario": "cloudflare-think-instrumentation", "variants": [ { - "variantKey": "cloudflare-think-v0", - "label": "v0.13 pinned" + "variantKey": "cloudflare-think-v0-13-ai6", + "label": "v0.13 pinned / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-13-ai6-manual", + "cloudflare-think-v0-13-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-13-latest-ai6", + "label": "v0.13 latest / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-13-latest-ai6-manual", + "cloudflare-think-v0-13-latest-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-14-ai6", + "label": "v0.14 pinned / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-14-ai6-manual", + "cloudflare-think-v0-14-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-14-latest-ai6", + "label": "v0.14 latest / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-14-latest-ai6-manual", + "cloudflare-think-v0-14-latest-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-15-ai6", + "label": "v0.15 pinned / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-15-ai6-manual", + "cloudflare-think-v0-15-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-15-latest-ai6", + "label": "v0.15 latest / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-15-latest-ai6-manual", + "cloudflare-think-v0-15-latest-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-16-ai6", + "label": "v0.16 pinned / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-16-ai6-manual", + "cloudflare-think-v0-16-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-16-latest-ai6", + "label": "v0.16 latest / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-16-latest-ai6-manual", + "cloudflare-think-v0-16-latest-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-17-ai6", + "label": "v0.17 pinned / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-17-ai6-manual", + "cloudflare-think-v0-17-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-17-latest-ai6", + "label": "v0.17 latest / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-17-latest-ai6-manual", + "cloudflare-think-v0-17-latest-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-18-ai6", + "label": "v0.18 pinned / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-18-ai6-manual", + "cloudflare-think-v0-18-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-18-latest-ai6", + "label": "v0.18 latest / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-18-latest-ai6-manual", + "cloudflare-think-v0-18-latest-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-19-ai6", + "label": "v0.19 pinned / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-19-ai6-manual", + "cloudflare-think-v0-19-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-19-latest-ai6", + "label": "v0.19 latest / AI SDK 6", + "variantKeys": [ + "cloudflare-think-v0-19-latest-ai6-manual", + "cloudflare-think-v0-19-latest-ai6-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-15-ai7", + "label": "v0.15 pinned / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-15-ai7-manual", + "cloudflare-think-v0-15-ai7-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-15-latest-ai7", + "label": "v0.15 latest / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-15-latest-ai7-manual", + "cloudflare-think-v0-15-latest-ai7-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-16-ai7", + "label": "v0.16 pinned / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-16-ai7-manual", + "cloudflare-think-v0-16-ai7-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-16-latest-ai7", + "label": "v0.16 latest / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-16-latest-ai7-manual", + "cloudflare-think-v0-16-latest-ai7-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-17-ai7", + "label": "v0.17 pinned / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-17-ai7-manual", + "cloudflare-think-v0-17-ai7-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-17-latest-ai7", + "label": "v0.17 latest / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-17-latest-ai7-manual", + "cloudflare-think-v0-17-latest-ai7-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-18-ai7", + "label": "v0.18 pinned / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-18-ai7-manual", + "cloudflare-think-v0-18-ai7-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-18-latest-ai7", + "label": "v0.18 latest / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-18-latest-ai7-manual", + "cloudflare-think-v0-18-latest-ai7-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-19-ai7", + "label": "v0.19 pinned / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-19-ai7-manual", + "cloudflare-think-v0-19-ai7-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-19-latest-ai7", + "label": "v0.19 latest / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-19-latest-ai7-manual", + "cloudflare-think-v0-19-latest-ai7-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-20-ai7", + "label": "v0.20 pinned / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-20-ai7-manual", + "cloudflare-think-v0-20-ai7-auto" + ] + }, + { + "variantKey": "cloudflare-think-v0-20-latest-ai7", + "label": "v0.20 latest / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-20-latest-ai7-manual", + "cloudflare-think-v0-20-latest-ai7-auto" + ] }, { - "variantKey": "cloudflare-think-v0-latest", - "label": "v0.13 latest" + "variantKey": "cloudflare-think-v0-20-1-ai7", + "label": "v0.20.1 / AI SDK 7", + "variantKeys": [ + "cloudflare-think-v0-20-1-ai7-manual", + "cloudflare-think-v0-20-1-ai7-auto" + ] } ] }, diff --git a/e2e/helpers/pr-e2e-links.test.ts b/e2e/helpers/pr-e2e-links.test.ts index b2e08eb1a..c99c63fcd 100644 --- a/e2e/helpers/pr-e2e-links.test.ts +++ b/e2e/helpers/pr-e2e-links.test.ts @@ -25,6 +25,19 @@ it("links published runs while preserving legacy records and excluding local-onl label: name, metadataScenario: name, })), + { + scenarioDirName: "grouped", + label: "Grouped", + metadataScenario: "grouped", + variants: [ + { + variantKey: "v1", + label: "v1", + variantKeys: ["v1-manual", "v1-auto"], + }, + { variantKey: "v2", label: "v2" }, + ], + }, ]), ); await writeFile( @@ -54,6 +67,14 @@ it("links published runs while preserving legacy records and excluding local-onl logRootSpanIds: [], experimentNames: [], }, + ...["manual", "auto"].map((mode) => ({ + scenarioDirName: "grouped", + variantKey: `v1-${mode}`, + testRunId: `e2e-${mode}`, + forwardToProduction: true, + logRootSpanIds: [`trace-${mode}`], + experimentNames: [], + })), ] .map((record) => JSON.stringify({ scenarioDirName: "scenario", ...record }), @@ -82,7 +103,7 @@ it("links published runs while preserving legacy records and excluding local-onl expect(stdout).toContain("e2e-legacy"); expect(stdout).not.toContain("e2e-local-only"); const logsLinks = [...stdout.matchAll(/\[Open logs\]\(([^)]+)\)/g)]; - expect(logsLinks).toHaveLength(2); + expect(logsLinks).toHaveLength(3); const search = JSON.parse( new URL(logsLinks[1][1]).searchParams.get("search")!, ); @@ -92,6 +113,18 @@ it("links published runs while preserving legacy records and excluding local-onl expect(stdout).toContain("/experiments/eval%2Fwith%20spaces"); expect(stdout).toContain("| empty | N/A | Observed (no captured traces) |"); expect(stdout).not.toContain("e2e-eval"); + const groupedSearch = JSON.parse( + new URL(logsLinks[2][1]).searchParams.get("search")!, + ); + expect(decodeURIComponent(groupedSearch.filter[0].text)).toBe( + '(root_span_id IN ("trace-manual", "trace-auto"))', + ); + expect(stdout).toContain("| Grouped (v1) |"); + expect(stdout).toContain("| Observed (2 runs) |"); + expect(stdout).toContain( + "| Grouped (v2) | N/A | Not observed in this run |", + ); + expect(stdout).not.toContain("unconfigured variant"); } finally { await rm(dir, { recursive: true, force: true }); } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-ai6-auto.cassette.json new file mode 100644 index 000000000..2a1050501 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:06:11.494Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb11MylQ3NxFKY9RDCuMd8vnq0Cxh\",\"object\":\"chat.completion.chunk\",\"created\":1792490768,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_OrxBCuerKHC4g1DQ8mvdsUQE\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2xGVyTnw1vjCF\"}", + "data: {\"id\":\"chatcmpl-Eb11MylQ3NxFKY9RDCuMd8vnq0Cxh\",\"object\":\"chat.completion.chunk\",\"created\":1792490768,\"model\":\"gpt-5-nano-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\":\"vZCJnXnBZq\"}", + "data: {\"id\":\"chatcmpl-Eb11MylQ3NxFKY9RDCuMd8vnq0Cxh\",\"object\":\"chat.completion.chunk\",\"created\":1792490768,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bfPYnWu3C\"}", + "data: {\"id\":\"chatcmpl-Eb11MylQ3NxFKY9RDCuMd8vnq0Cxh\",\"object\":\"chat.completion.chunk\",\"created\":1792490768,\"model\":\"gpt-5-nano-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\":\"cdjO8QeA\"}", + "data: {\"id\":\"chatcmpl-Eb11MylQ3NxFKY9RDCuMd8vnq0Cxh\",\"object\":\"chat.completion.chunk\",\"created\":1792490768,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KJwDLxpMU\"}", + "data: {\"id\":\"chatcmpl-Eb11MylQ3NxFKY9RDCuMd8vnq0Cxh\",\"object\":\"chat.completion.chunk\",\"created\":1792490768,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i3KgdT5vRgU\"}", + "data: {\"id\":\"chatcmpl-Eb11MylQ3NxFKY9RDCuMd8vnq0Cxh\",\"object\":\"chat.completion.chunk\",\"created\":1792490768,\"model\":\"gpt-5-nano-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\":\"okDn9OeCXF\"}", + "data: {\"id\":\"chatcmpl-Eb11MylQ3NxFKY9RDCuMd8vnq0Cxh\",\"object\":\"chat.completion.chunk\",\"created\":1792490768,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"ahZwdBQhsfs\"}", + "data: {\"id\":\"chatcmpl-Eb11MylQ3NxFKY9RDCuMd8vnq0Cxh\",\"object\":\"chat.completion.chunk\",\"created\":1792490768,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"mgtr6aFfE92EjYs\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73547dd9f6662-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:06:11 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2586", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_f7222036f42749888c225e3ed5d598a6" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "8cac9a63e098fb1e", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:06:13.418Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_OrxBCuerKHC4g1DQ8mvdsUQE", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_OrxBCuerKHC4g1DQ8mvdsUQE" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zjf0Y\"}", + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ihf\"}", + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8vwvY\"}", + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Own5\"}", + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"d\"}", + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mWI\"}", + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rrEHdN\"}", + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"a1Bb6\"}", + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"j8PDC\"}", + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OIyqdD\"}", + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"I\"}", + "data: {\"id\":\"chatcmpl-Eb11P4CxqbWrBlV24jC9rBox8jles\",\"object\":\"chat.completion.chunk\",\"created\":1792490771,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"oaqcjEXuIrro2oW\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d7355a4d416662-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:06:13 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1574", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_20ca83cf7294493b94abfdda7e3ee792" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:29.955Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-ai6-manual.cassette.json new file mode 100644 index 000000000..4f0cdb900 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:05:59.785Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb11BKVtn13rekc7XCVaNBZSWhf6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490757,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_WticruDC3rYJfd0POlzKsK3m\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"z29hngyjflbga\"}", + "data: {\"id\":\"chatcmpl-Eb11BKVtn13rekc7XCVaNBZSWhf6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490757,\"model\":\"gpt-5-nano-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\":\"He3fXODjxp\"}", + "data: {\"id\":\"chatcmpl-Eb11BKVtn13rekc7XCVaNBZSWhf6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490757,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YLcRIiezM\"}", + "data: {\"id\":\"chatcmpl-Eb11BKVtn13rekc7XCVaNBZSWhf6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490757,\"model\":\"gpt-5-nano-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\":\"znn3N0nm\"}", + "data: {\"id\":\"chatcmpl-Eb11BKVtn13rekc7XCVaNBZSWhf6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490757,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nLQmoTuF3\"}", + "data: {\"id\":\"chatcmpl-Eb11BKVtn13rekc7XCVaNBZSWhf6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490757,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"A3EVEmSlWwc\"}", + "data: {\"id\":\"chatcmpl-Eb11BKVtn13rekc7XCVaNBZSWhf6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490757,\"model\":\"gpt-5-nano-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\":\"ffzbRQ5Mtr\"}", + "data: {\"id\":\"chatcmpl-Eb11BKVtn13rekc7XCVaNBZSWhf6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490757,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"O1p2E1w5MQI\"}", + "data: {\"id\":\"chatcmpl-Eb11BKVtn13rekc7XCVaNBZSWhf6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490757,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"UsiBOySABDRBGDY\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d734fcfcc8f0bf-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:05:59 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2623", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_a6e09cc7a9cc48e2b599ec82890002c4" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "fe4e667eaa21a781", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:06:01.752Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_WticruDC3rYJfd0POlzKsK3m", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_WticruDC3rYJfd0POlzKsK3m" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nihsE\"}", + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ReJ\"}", + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VVyCZ\"}", + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Up0c\"}", + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"O\"}", + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lF4\"}", + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i6gjMg\"}", + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1XUZR\"}", + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4UTcF\"}", + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"StllYg\"}", + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"5\"}", + "data: {\"id\":\"chatcmpl-Eb11EhVwRdpNxqSWCGB5DK2AU3VjQ\",\"object\":\"chat.completion.chunk\",\"created\":1792490760,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"XojWb2CQwM516Bi\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73510fe39f0bf-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:06:01 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1603", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_da2b5c68ad704babb36ce636e0cfd767" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:28.018Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-latest-ai6-auto.cassette.json new file mode 100644 index 000000000..45a84e0f1 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-latest-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:06:37.137Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb11ndD3O3tpWpPo4cPfUGpm6A0PI\",\"object\":\"chat.completion.chunk\",\"created\":1792490795,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_gDW96UGObp9R4riH43Rd0Swu\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kT4nUBYo5yLmD\"}", + "data: {\"id\":\"chatcmpl-Eb11ndD3O3tpWpPo4cPfUGpm6A0PI\",\"object\":\"chat.completion.chunk\",\"created\":1792490795,\"model\":\"gpt-5-nano-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\":\"gM0ljtp5Lo\"}", + "data: {\"id\":\"chatcmpl-Eb11ndD3O3tpWpPo4cPfUGpm6A0PI\",\"object\":\"chat.completion.chunk\",\"created\":1792490795,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RQnHzXYP3\"}", + "data: {\"id\":\"chatcmpl-Eb11ndD3O3tpWpPo4cPfUGpm6A0PI\",\"object\":\"chat.completion.chunk\",\"created\":1792490795,\"model\":\"gpt-5-nano-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\":\"dVICHnxZ\"}", + "data: {\"id\":\"chatcmpl-Eb11ndD3O3tpWpPo4cPfUGpm6A0PI\",\"object\":\"chat.completion.chunk\",\"created\":1792490795,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tAudAUpsE\"}", + "data: {\"id\":\"chatcmpl-Eb11ndD3O3tpWpPo4cPfUGpm6A0PI\",\"object\":\"chat.completion.chunk\",\"created\":1792490795,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"esCIw8sStvI\"}", + "data: {\"id\":\"chatcmpl-Eb11ndD3O3tpWpPo4cPfUGpm6A0PI\",\"object\":\"chat.completion.chunk\",\"created\":1792490795,\"model\":\"gpt-5-nano-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\":\"mpvxrdUw08\"}", + "data: {\"id\":\"chatcmpl-Eb11ndD3O3tpWpPo4cPfUGpm6A0PI\",\"object\":\"chat.completion.chunk\",\"created\":1792490795,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"ISHdIChye2Y\"}", + "data: {\"id\":\"chatcmpl-Eb11ndD3O3tpWpPo4cPfUGpm6A0PI\",\"object\":\"chat.completion.chunk\",\"created\":1792490795,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"6WptYfeow8NiXIR\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d735ecfc99f18a-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:06:36 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1742", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_2a92d20d664d46e894599825a203a545" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "68169a99cd3c8537", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:06:40.570Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_gDW96UGObp9R4riH43Rd0Swu", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_gDW96UGObp9R4riH43Rd0Swu" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LNNan\"}", + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nr3\"}", + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"BRbrY\"}", + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Q4DA\"}", + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"T\"}", + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PvX\"}", + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2HvcwR\"}", + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tgrVA\"}", + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"O1s1a\"}", + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"NlRSHi\"}", + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"Q\"}", + "data: {\"id\":\"chatcmpl-Eb11p6acuIBUFtvXxTPmbmKpVX7NT\",\"object\":\"chat.completion.chunk\",\"created\":1792490797,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":338,\"total_tokens\":1425,\"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\":\"65bIsblGvI0OYLX\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d735fa6a35f18a-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:06:40 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2953", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_44f25324d4fe4b5dab85b18240a27c71" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:34.435Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-latest-ai6-manual.cassette.json new file mode 100644 index 000000000..83a5a2140 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-13-latest-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:06:23.377Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb11ZFESTAEdvIF3pYPx6HZRKbD6m\",\"object\":\"chat.completion.chunk\",\"created\":1792490781,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_hMmtWwPKYkl6YWT2M68H6Dwr\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Kq1V2X17s2UlP\"}", + "data: {\"id\":\"chatcmpl-Eb11ZFESTAEdvIF3pYPx6HZRKbD6m\",\"object\":\"chat.completion.chunk\",\"created\":1792490781,\"model\":\"gpt-5-nano-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\":\"qaAKHHr0hE\"}", + "data: {\"id\":\"chatcmpl-Eb11ZFESTAEdvIF3pYPx6HZRKbD6m\",\"object\":\"chat.completion.chunk\",\"created\":1792490781,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ynRBEl9YG\"}", + "data: {\"id\":\"chatcmpl-Eb11ZFESTAEdvIF3pYPx6HZRKbD6m\",\"object\":\"chat.completion.chunk\",\"created\":1792490781,\"model\":\"gpt-5-nano-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\":\"itMi4uA6\"}", + "data: {\"id\":\"chatcmpl-Eb11ZFESTAEdvIF3pYPx6HZRKbD6m\",\"object\":\"chat.completion.chunk\",\"created\":1792490781,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nm3TO5J1S\"}", + "data: {\"id\":\"chatcmpl-Eb11ZFESTAEdvIF3pYPx6HZRKbD6m\",\"object\":\"chat.completion.chunk\",\"created\":1792490781,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OglDWiGSc0x\"}", + "data: {\"id\":\"chatcmpl-Eb11ZFESTAEdvIF3pYPx6HZRKbD6m\",\"object\":\"chat.completion.chunk\",\"created\":1792490781,\"model\":\"gpt-5-nano-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\":\"fQaHJ1JlCf\"}", + "data: {\"id\":\"chatcmpl-Eb11ZFESTAEdvIF3pYPx6HZRKbD6m\",\"object\":\"chat.completion.chunk\",\"created\":1792490781,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"UTpHDzmlWgg\"}", + "data: {\"id\":\"chatcmpl-Eb11ZFESTAEdvIF3pYPx6HZRKbD6m\",\"object\":\"chat.completion.chunk\",\"created\":1792490781,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"lywRLLORAJn7Xm1\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d735969e8a2879-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:06:23 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1696", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_a39560ce4f40484e8ddcbf98a4db5f65" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "bd752941bd3c5679", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:06:25.079Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_hMmtWwPKYkl6YWT2M68H6Dwr", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_hMmtWwPKYkl6YWT2M68H6Dwr" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8ovSf\"}", + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uOG\"}", + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VNdRn\"}", + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ABxA\"}", + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Y\"}", + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5RP\"}", + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rg8jV2\"}", + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6SgvL\"}", + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"V65qk\"}", + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OMwrS7\"}", + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"P\"}", + "data: {\"id\":\"chatcmpl-Eb11bUq6alM3VkAikgIlE71x4Lna4\",\"object\":\"chat.completion.chunk\",\"created\":1792490783,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"4zCEbDVPsJFZTqd\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d735a488742879-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:06:24 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1330", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_6881589806274de9b9565afa338a2936" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:32.204Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-auto.cassette.json new file mode 100644 index 000000000..ee6eb670c --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:07:04.280Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_WntIrLs2z7SHz7NmKcGeddJh\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DwMXJ7AB3sCEs\"}", + "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-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\":\"OutVzXa6Aa\"}", + "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jbJBo4ChU\"}", + "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-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\":\"nOnFhp6C\"}", + "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1zr3TEpf3\"}", + "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OtVRNWO2hls\"}", + "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-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\":\"6odyylcj6Y\"}", + "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"BTeG0IMEtUW\"}", + "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"IRVDLbojf4XS2Q6\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73694ab2f285a-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:07:04 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2146", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_ce630892ad294b019a6d250b82654d2e" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "6601b126a8bbb941", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:07:06.318Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_WntIrLs2z7SHz7NmKcGeddJh", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_WntIrLs2z7SHz7NmKcGeddJh" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JHFbH\"}", + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RpV\"}", + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Chvtp\"}", + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DEQk\"}", + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"o\"}", + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i7C\"}", + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RXbEC2\"}", + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ryvuE\"}", + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4CnNJ\"}", + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TFKfTA\"}", + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"N\"}", + "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"cEccvG0BXtacONI\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d736a43e9e285a-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:07:06 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1590", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_3a68223d8ae44ee5a02b3a5a5365f478" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:38.885Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-manual.cassette.json new file mode 100644 index 000000000..5c7fadb1b --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:06:51.969Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_jL3QS5Uw10fIKo573IaoJyNd\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"amPLE6qGZ83xm\"}", + "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-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\":\"1wCf9iAHsb\"}", + "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Zi0JPJeDd\"}", + "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-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\":\"e0Tt89Gc\"}", + "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sW7VQZxwi\"}", + "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZA8kPiJGViD\"}", + "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-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\":\"PQzdmYjhTq\"}", + "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"csETsQd7i8Q\"}", + "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":408,\"total_tokens\":1450,\"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\":\"hwzwVXqNJGLHkds\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73642bead5c46-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:06:51 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2826", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_5e405fd9ea354369ae4bd05f6319629d" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "a99b09a9027c25e7", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:06:53.944Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_jL3QS5Uw10fIKo573IaoJyNd", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_jL3QS5Uw10fIKo573IaoJyNd" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XgIEo\"}", + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1Mc\"}", + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"IgeeS\"}", + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i8eH\"}", + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"e\"}", + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"f5e\"}", + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"yLllvW\"}", + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5K3Sb\"}", + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EFoqz\"}", + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"b4XCLk\"}", + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"s\"}", + "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"26DejGyhx8lzZUr\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d736572e035c46-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:06:53 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1568", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_92baae7fdb9440c48f62e3f4639f9480" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:36.406Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-auto.cassette.json new file mode 100644 index 000000000..c3771303d --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:07:27.498Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_Fy7dnfNrX4wpSdBmqSZewows\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ONon663AzIDhr\"}", + "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-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\":\"ZI12ll4qAt\"}", + "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cawWXGA2K\"}", + "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-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\":\"tyFD2ja8\"}", + "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"O8LUlfIFl\"}", + "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"veTn2H6YhHg\"}", + "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-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\":\"x4rcdgXHSd\"}", + "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"RALZDT8kDbD\"}", + "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"ddLXkhhSFHD8N7R\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d737251a8d9f0b-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:07:27 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2220", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_7c700d5ed8d247a58a005872f8e0945a" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "536e62020edfbe2d", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:07:28.239Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_Fy7dnfNrX4wpSdBmqSZewows", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_Fy7dnfNrX4wpSdBmqSZewows" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VLPOG\"}", + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"W3s\"}", + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3nNac\"}", + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nNbL\"}", + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"C\"}", + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ifj\"}", + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wHe6Lx\"}", + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FKOxr\"}", + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gw76L\"}", + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dh0sSa\"}", + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"M\"}", + "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":12,\"total_tokens\":1099,\"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\":\"XS\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73735490f9f0b-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:07:28 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "261", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_f77442da99d74671be82af7f414a1114" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:42.847Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-manual.cassette.json new file mode 100644 index 000000000..b70a7e30e --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:07:16.914Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_S2jmaDTpfK7KQxjcJVppe4oM\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mipPsYzjtQJmX\"}", + "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-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\":\"5f2v8IbaHF\"}", + "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PE81YwnOR\"}", + "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-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\":\"PRQnKOe2\"}", + "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"oCLZjcOFj\"}", + "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"l218J0J8jfa\"}", + "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-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\":\"WFRh8u533M\"}", + "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"Z1nGKhFdrxK\"}", + "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"t2dXfKZAzZQo2dI\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d736e5addd5925-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:07:16 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1810", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_734d3231cd4d4c84a025a99f1a5a83da" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "6582b413e162207c", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:07:17.614Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_S2jmaDTpfK7KQxjcJVppe4oM", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_S2jmaDTpfK7KQxjcJVppe4oM" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PyT99\"}", + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Haq\"}", + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5euWl\"}", + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OShI\"}", + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"X\"}", + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9fD\"}", + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"czvcmC\"}", + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uzZqz\"}", + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"y23iW\"}", + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tpr5A2\"}", + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"j\"}", + "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":12,\"total_tokens\":1099,\"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\":\"1i\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d736f30c4a5925-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:07:17 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "303", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_e36d9c1924ba4717b1280a182032fb2a" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:40.624Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-auto.cassette.json new file mode 100644 index 000000000..1c3e29138 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:07:57.109Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_8PnGbmPhJTaq74kxntGSfTNS\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Jbbnl7Lfeyazy\"}", + "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-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\":\"xKjZfAe30Z\"}", + "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6tBAIGpiy\"}", + "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-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\":\"ifU7vApF\"}", + "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"41uXlwoqY\"}", + "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"G3hMQG5VIM0\"}", + "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-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\":\"26LQovFCic\"}", + "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"jo3npxv0UNI\"}", + "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":472,\"total_tokens\":1514,\"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\":\"Y1Zabh92MDqSBmT\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d737d0ba1c2a41-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:07:57 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "4401", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_0d50b353c30e4a1795a500e58a6e99a9" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "014d6609e3bdf228", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:07:58.681Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_8PnGbmPhJTaq74kxntGSfTNS", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_8PnGbmPhJTaq74kxntGSfTNS" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EGkOV\"}", + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4WN\"}", + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xs3oo\"}", + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mUOp\"}", + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"M\"}", + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WFe\"}", + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"D3ew3i\"}", + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dkRc4\"}", + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tXv8i\"}", + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HBCr9w\"}", + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"z\"}", + "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":82,\"total_tokens\":1169,\"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\":\"D\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d737ee4d502a41-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:07:58 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1197", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_fc39267ea33a4297bb54d05fd64e30ec" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:46.525Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-manual.cassette.json new file mode 100644 index 000000000..09101b64c --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:07:41.291Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_5sJ3ggTZXX0MgY7V0DEerfyu\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"CKfXZ2C3TFiYH\"}", + "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-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\":\"QRxixMB9VP\"}", + "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vwbCmeaKl\"}", + "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-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\":\"CRaheg5f\"}", + "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7Hz2AgaDP\"}", + "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lFI1Na3lhaS\"}", + "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-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\":\"bSAfktUZ8l\"}", + "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"oyGjeX43yv7\"}", + "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"oONvOX2nU54xcS6\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d737763d13f5e7-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:07:41 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3009", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_ec039d1dd52d4c419890c9227d1ecf5d" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "2358d1a0d54080ca", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:07:43.769Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_5sJ3ggTZXX0MgY7V0DEerfyu", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_5sJ3ggTZXX0MgY7V0DEerfyu" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sN5Jt\"}", + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zc2\"}", + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zCUQQ\"}", + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"m668\"}", + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"s\"}", + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7oX\"}", + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"CpmiUY\"}", + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cSA0i\"}", + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5xlie\"}", + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XjlD0j\"}", + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"1\"}", + "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"g8KJl9aR78qBsf2\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d7378da8e3f5e7-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:07:43 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1776", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_550d7558803c464894666c310058d235" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:44.569Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-auto.cassette.json new file mode 100644 index 000000000..488d6e0e3 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:10:14.813Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_gpZJTMgposhEGy6FQcWKr6Nr\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gvBEsOWSOjvi1\"}", + "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-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\":\"PzuzR5u4Y4\"}", + "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"QKFueB3Yy\"}", + "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-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\":\"Z0kKqCi1\"}", + "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OwTTDxCZy\"}", + "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6lwArIRQbDR\"}", + "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-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\":\"cZEXiMQd5x\"}", + "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"jhIfv0Huo8E\"}", + "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"G5XjoIGzKsXrhaA\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73b3b6ab15671-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:10:14 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2160", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_45d4c91efcd44077b0019bbf78deca33" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "1901af6f191db57b", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:10:16.957Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_gpZJTMgposhEGy6FQcWKr6Nr", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_gpZJTMgposhEGy6FQcWKr6Nr" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2hwrG\"}", + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Soy\"}", + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hyoAn\"}", + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KOFH\"}", + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"I\"}", + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Ldn\"}", + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"NHcYI0\"}", + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Rjf6U\"}", + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HEYa9\"}", + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LGsmdr\"}", + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"t\"}", + "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"hT9ZYvgW0Vf3rTJ\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73b4ade4e5671-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:10:16 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1799", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_857a472480f44f9da6a7a3baa378600b" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:01.626Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-manual.cassette.json new file mode 100644 index 000000000..eae78406e --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:10:04.387Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_2sQ4szXYNBlGMYfAGU0mE2hz\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"f1sDP2ejLkkKa\"}", + "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-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\":\"ZIHMjp8vld\"}", + "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"d5rXUL7Qd\"}", + "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-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\":\"03C7pNjz\"}", + "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JbzxifZwq\"}", + "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tLlMPLTZHD3\"}", + "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-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\":\"7HQ5ar1mVC\"}", + "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"QSTL36BeEPh\"}", + "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"kZe8aq7ckRPqjjj\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73af488f6595b-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:10:04 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3051", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_ba68a241c52b44919d3ca482993ad01a" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "37bca3468bb735fe", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:10:04.983Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_2sQ4szXYNBlGMYfAGU0mE2hz", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_2sQ4szXYNBlGMYfAGU0mE2hz" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DsPUb\"}", + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kX6\"}", + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"naMvK\"}", + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"su4j\"}", + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Z\"}", + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jIq\"}", + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9PGtmK\"}", + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"GcfLc\"}", + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5CsSF\"}", + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eKbeYJ\"}", + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"A\"}", + "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":12,\"total_tokens\":1099,\"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\":\"HX\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73b09cf08595b-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:10:04 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "251", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_46d964cec48b4c7f8770ffe225379bad" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:59:59.395Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-auto.cassette.json new file mode 100644 index 000000000..734868893 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:12:53.459Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_muWWJ3dJhjQZWwre0OGM51I5\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RE3rvhiYaqfvq\"}", + "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-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\":\"Oeqh1u98lm\"}", + "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pnikdeY18\"}", + "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-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\":\"ZBLAjTfk\"}", + "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"aMOCHPAAM\"}", + "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"QAHW6sre0wC\"}", + "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-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\":\"6dQvIA575j\"}", + "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"CS88OmTy1p1\"}", + "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":408,\"total_tokens\":1450,\"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\":\"VMvFipALh3uMg0d\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73f1568bb97c1-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:12:53 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3018", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_59a42e5048fe43869752c53939d296fd" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "1a3acc1c808b7b73", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:12:55.220Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_muWWJ3dJhjQZWwre0OGM51I5", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_muWWJ3dJhjQZWwre0OGM51I5" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eVHYr\"}", + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"AnT\"}", + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TdjNY\"}", + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lwnG\"}", + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"J\"}", + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EH6\"}", + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Q3LV70\"}", + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YrqPQ\"}", + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jEfCt\"}", + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8FEKab\"}", + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"C\"}", + "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"jitk9iUW2jweUyL\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73f2a48e097c1-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:12:55 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1441", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_0b0671259b994fb39309e7d537599a12" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:50.422Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-manual.cassette.json new file mode 100644 index 000000000..4e46e598e --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:12:40.581Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_tp0s1nPH8BcRQ0PCs3jmPllM\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xgkBFkEGP3mtU\"}", + "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-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\":\"sRofcMTb0t\"}", + "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XtYJs2SRW\"}", + "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-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\":\"0soujTOC\"}", + "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wTm7eYfra\"}", + "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6PJMSkpcpdl\"}", + "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-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\":\"9ssag0ZsKm\"}", + "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"xi28xnJJiL9\"}", + "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"qqZb9FSTlU4MuYc\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73ec808779ed8-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:12:40 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2469", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_fc03c8b837fc4e9ea8eb4d22a0d98e6a" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "749a4127e331fdea", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:12:42.728Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_tp0s1nPH8BcRQ0PCs3jmPllM", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_tp0s1nPH8BcRQ0PCs3jmPllM" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"oC4FS\"}", + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pv4\"}", + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1vaY6\"}", + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"M6uM\"}", + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"U\"}", + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"86H\"}", + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"reY1Nu\"}", + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FnI7K\"}", + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9XN9h\"}", + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8xrNsh\"}", + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"t\"}", + "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"h07heTeP8GFlF7y\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73ed9d9c29ed8-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:12:42 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1821", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_6e8a548c92154d80a271c491d281cba5" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:48.473Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-auto.cassette.json new file mode 100644 index 000000000..84eaad06a --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:17:30.828Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_hbRLyJXQCbwABaT8JkqxU3UT\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sXipdyam8y7AH\"}", + "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-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\":\"tuKxl0vnde\"}", + "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XbB3cP1le\"}", + "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-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\":\"onPQCtAm\"}", + "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EG1EWO9cr\"}", + "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ElNhWc9dwej\"}", + "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-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\":\"gkRGhiF8Eh\"}", + "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"fbKBnk5rZkr\"}", + "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"JKC7IaRTimLh80m\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d745dec8e00e6c-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:17:30 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2355", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_785527edebd54757bd38c2d383dd08c2" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "70d11c0d66618968", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:17:33.028Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_hbRLyJXQCbwABaT8JkqxU3UT", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_hbRLyJXQCbwABaT8JkqxU3UT" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jz8O8\"}", + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5q5\"}", + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7AExw\"}", + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Zgx9\"}", + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"J\"}", + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"NyD\"}", + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PRElOz\"}", + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7dEOJ\"}", + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Z4jye\"}", + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kshQcC\"}", + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"N\"}", + "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"tzE1LKT4puwVyWO\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d745efec530e6c-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:17:32 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1741", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_818d779af06b44a5bc542273e8e3c1dc" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:05.854Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-manual.cassette.json new file mode 100644 index 000000000..4a8193491 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:17:17.897Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_vos6htgeYnbxPjJb2V83vkNg\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TctEXeabrM8ej\"}", + "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-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\":\"8zgk4M5Fmt\"}", + "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FsEGuJPnd\"}", + "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-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\":\"iUal197b\"}", + "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"L98iZicRR\"}", + "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gMrytTWvFc5\"}", + "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-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\":\"NZBty39Wgg\"}", + "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"wrcmO1Rn0Iu\"}", + "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":536,\"total_tokens\":1578,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"completion_tokens_details\":{\"reasoning_tokens\":512,\"audio_tokens\":0,\"accepted_prediction_tokens\":0,\"rejected_prediction_tokens\":0}},\"obfuscation\":\"okMs4ivv8GYtHmP\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d745851f376fdc-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:17:17 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3638", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_d36b992da0d047bdb5c81cb232e789f5" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "5865068e42732297", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:17:20.451Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_vos6htgeYnbxPjJb2V83vkNg", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_vos6htgeYnbxPjJb2V83vkNg" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"D3etl\"}", + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"r4u\"}", + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gSwYh\"}", + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"51P6\"}", + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"w\"}", + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"B37\"}", + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gqyp9l\"}", + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1xkKX\"}", + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"inp1p\"}", + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rfc12Q\"}", + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"I\"}", + "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"PkNgICQplBUoOrz\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d7459f384f6fdc-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:17:20 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2022", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_5bb08531aee5455f899afd70180e0281" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:03.619Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-auto.cassette.json new file mode 100644 index 000000000..4d83edd92 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:08:30.707Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_73X26MC9vqhB9FCNMlaLkqjM\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5T1fQW8T2pN4A\"}", + "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-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\":\"TVvf2EdycH\"}", + "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WzJcg0hsO\"}", + "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-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\":\"FXAXgLbS\"}", + "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"akZXVZUwN\"}", + "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hqK0ubxuTGj\"}", + "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-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\":\"nY4bkzm68q\"}", + "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"TXXl65Wa59E\"}", + "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"0WCi88vrqlpzRyL\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d738ab5a59aea3-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:08:30 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3010", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_87b7e7ab9d8649a0882d2c19704bcb4d" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "3ed8f5def82c2711", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:08:33.530Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_73X26MC9vqhB9FCNMlaLkqjM", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_73X26MC9vqhB9FCNMlaLkqjM" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KYXHP\"}", + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Vdf\"}", + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zYjcp\"}", + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"I49W\"}", + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"e\"}", + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0UI\"}", + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0rote7\"}", + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dYIbF\"}", + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cmsBY\"}", + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zn6u3p\"}", + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"K\"}", + "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"FDyHZnNW411e6o9\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d738c039f6aea3-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:08:33 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2401", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_da8ac88bbc0948ae92e7f1bf6c1513d8" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:54.341Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-manual.cassette.json new file mode 100644 index 000000000..d59ae3763 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:08:16.547Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_scbVS2oAyX7SrQdGRaDNoWf3\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DQJDYeCRoZS8p\"}", + "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-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\":\"GZF0t3IIYc\"}", + "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mkxkBO3C3\"}", + "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-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\":\"RAzTqXTA\"}", + "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WzHnQj6I5\"}", + "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EChkz8VrPhM\"}", + "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-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\":\"TQhzrixYe4\"}", + "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"oc1vEJdGvL6\"}", + "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":600,\"total_tokens\":1642,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"completion_tokens_details\":{\"reasoning_tokens\":576,\"audio_tokens\":0,\"accepted_prediction_tokens\":0,\"rejected_prediction_tokens\":0}},\"obfuscation\":\"cCVpjenufbDYAVn\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d738475cf10cb6-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:08:16 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "4851", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_ba7ed9f1b569430bb46ad15698b91365" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "cb76030617d60e51", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:08:19.264Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_scbVS2oAyX7SrQdGRaDNoWf3", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_scbVS2oAyX7SrQdGRaDNoWf3" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"qzSa2\"}", + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"NBP\"}", + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"SPnRu\"}", + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ayVy\"}", + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"w\"}", + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KFm\"}", + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PBRath\"}", + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"89Jdk\"}", + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"m2Oyp\"}", + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"48Y7dp\"}", + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"H\"}", + "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"HElpZwJOoxmEAkn\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73867cd780cb6-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:08:19 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2307", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_2d56ee4f2977471ca9aab5231ebeb3f9" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:52.124Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-latest-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-auto.cassette.json similarity index 85% rename from e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-latest-manual.cassette.json rename to e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-auto.cassette.json index e784c5828..b23e6b261 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-latest-manual.cassette.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-auto.cassette.json @@ -4,7 +4,7 @@ "callIndex": 0, "id": "02bfffc5f7e45fcc", "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-07-20T14:52:10.061Z", + "recordedAt": "2026-10-20T10:10:49.602Z", "request": { "body": { "kind": "json", @@ -268,15 +268,15 @@ "response": { "body": { "chunks": [ - "data: {\"id\":\"chatcmpl-E3jdeRufBpWdcnlvefQEVX1AaGDvd\",\"object\":\"chat.completion.chunk\",\"created\":1784559126,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_Eoiiczb05o0gHVdCT1udMEQS\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"x8G82KK4NhJqf\"}", - "data: {\"id\":\"chatcmpl-E3jdeRufBpWdcnlvefQEVX1AaGDvd\",\"object\":\"chat.completion.chunk\",\"created\":1784559126,\"model\":\"gpt-5-nano-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\":\"pSTXLgOXRH\"}", - "data: {\"id\":\"chatcmpl-E3jdeRufBpWdcnlvefQEVX1AaGDvd\",\"object\":\"chat.completion.chunk\",\"created\":1784559126,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Z0Tw1OsB1\"}", - "data: {\"id\":\"chatcmpl-E3jdeRufBpWdcnlvefQEVX1AaGDvd\",\"object\":\"chat.completion.chunk\",\"created\":1784559126,\"model\":\"gpt-5-nano-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\":\"YlWdjNah\"}", - "data: {\"id\":\"chatcmpl-E3jdeRufBpWdcnlvefQEVX1AaGDvd\",\"object\":\"chat.completion.chunk\",\"created\":1784559126,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hveMd98Be\"}", - "data: {\"id\":\"chatcmpl-E3jdeRufBpWdcnlvefQEVX1AaGDvd\",\"object\":\"chat.completion.chunk\",\"created\":1784559126,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Q2kiGorklVn\"}", - "data: {\"id\":\"chatcmpl-E3jdeRufBpWdcnlvefQEVX1AaGDvd\",\"object\":\"chat.completion.chunk\",\"created\":1784559126,\"model\":\"gpt-5-nano-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\":\"TUAPImAvI5\"}", - "data: {\"id\":\"chatcmpl-E3jdeRufBpWdcnlvefQEVX1AaGDvd\",\"object\":\"chat.completion.chunk\",\"created\":1784559126,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"xDHwRJsdaf1\"}", - "data: {\"id\":\"chatcmpl-E3jdeRufBpWdcnlvefQEVX1AaGDvd\",\"object\":\"chat.completion.chunk\",\"created\":1784559126,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":472,\"total_tokens\":1514,\"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\":\"hzudExOv18nATcS\"}", + "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_CujcwW1ft7CAoVQy3oc1dFgs\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"B5zz8OOCTjY1S\"}", + "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-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\":\"3BCeqZP6mV\"}", + "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mLERB2jH6\"}", + "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-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\":\"W7N2mUdy\"}", + "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i0ctHXANr\"}", + "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rSiKDugOdhp\"}", + "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-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\":\"028ZqbwZfX\"}", + "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"TFBIN6n3PYR\"}", + "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"0ROx5C5Mshb0KPE\"}", "data: [DONE]" ], "kind": "sse" @@ -285,37 +285,34 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "a1e2c9a898bad6bb-IAD", - "connection": "keep-alive", + "cf-ray": "a4d73c14ecc590cc-AMS", "content-type": "text/event-stream; charset=utf-8", - "date": "Mon, 20 Jul 2026 14:52:09 GMT", + "date": "Tue, 20 Oct 2026 10:10:49 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "4024", + "openai-processing-ms": "2110", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "transfer-encoding": "chunked", "x-content-type-options": "nosniff", "x-openai-proxy-wasm": "v0.1", "x-ratelimit-limit-requests": "30000", "x-ratelimit-limit-tokens": "180000000", "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-remaining-tokens": "179999805", "x-ratelimit-reset-requests": "2ms", "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_3528a89f02aa41f08f950f46d92d2469" + "x-request-id": "req_a838f6854e7b490aa320830ff573c9d9" }, - "status": 200, - "statusText": "OK" + "status": 200 } }, { "callIndex": 1, - "id": "a62b9ef8bb70f1d5", + "id": "5350bfd34e8105a3", "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-07-20T14:52:12.986Z", + "recordedAt": "2026-10-20T10:10:52.158Z", "request": { "body": { "kind": "json", @@ -338,7 +335,7 @@ "arguments": "{\"city\":\"Vienna\"}", "name": "lookup_weather" }, - "id": "call_Eoiiczb05o0gHVdCT1udMEQS", + "id": "call_CujcwW1ft7CAoVQy3oc1dFgs", "type": "function" } ] @@ -346,7 +343,7 @@ { "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", "role": "tool", - "tool_call_id": "call_Eoiiczb05o0gHVdCT1udMEQS" + "tool_call_id": "call_CujcwW1ft7CAoVQy3oc1dFgs" } ], "model": "gpt-5-nano", @@ -598,18 +595,18 @@ "response": { "body": { "chunks": [ - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VuZbb\"}", - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"oam\"}", - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PUiJI\"}", - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"BeE7\"}", - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"V\"}", - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nWm\"}", - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KsqkxC\"}", - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5IY1X\"}", - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MclDT\"}", - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lcmbyj\"}", - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"V\"}", - "data: {\"id\":\"chatcmpl-E3jdik7STRo6NkYMCy1Eo7QC9KmO0\",\"object\":\"chat.completion.chunk\",\"created\":1784559130,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":338,\"total_tokens\":1425,\"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\":\"H2zk3oOvqddJbZo\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"65y3x\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Qq5\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZlV94\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Lqia\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"W\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uQk\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zpv2bD\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Y7y8Z\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Dl1de\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8j7Jsp\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"O\"}", + "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":338,\"total_tokens\":1425,\"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\":\"UJBs5uv1vUwAAHQ\"}", "data: [DONE]" ], "kind": "sse" @@ -618,18 +615,16 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "a1e2c9c33cc4d6bb-IAD", - "connection": "keep-alive", + "cf-ray": "a4d73c24d8e690cc-AMS", "content-type": "text/event-stream; charset=utf-8", - "date": "Mon, 20 Jul 2026 14:52:12 GMT", + "date": "Tue, 20 Oct 2026 10:10:52 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "2412", + "openai-processing-ms": "2111", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "transfer-encoding": "chunked", "x-content-type-options": "nosniff", "x-openai-proxy-wasm": "v0.1", "x-ratelimit-limit-requests": "30000", @@ -638,14 +633,13 @@ "x-ratelimit-remaining-tokens": "179999790", "x-ratelimit-reset-requests": "2ms", "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_5a41953636984f51aea4495cd220e137" + "x-request-id": "req_e6827b71a853436b9c472341fb4f640c" }, - "status": 200, - "statusText": "OK" + "status": 200 } } ], "meta": { - "createdAt": "2026-07-20T14:52:13.192Z" + "createdAt": "2026-10-20T10:00:10.058Z" } } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-manual.cassette.json new file mode 100644 index 000000000..e606feb74 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:10:36.325Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_esbImy3vmBN4m7P5aPKyVpnZ\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Vw6XEZLewlDKl\"}", + "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-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\":\"DNaoJ67Tjj\"}", + "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ExZM2NkSR\"}", + "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-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\":\"TlJAvse3\"}", + "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Etu0alv6q\"}", + "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"AZDFFd8i4uS\"}", + "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-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\":\"cq0i8qz9MA\"}", + "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"m2xJZd5HoD3\"}", + "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"u9BFsgackv7PEef\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73bc34b329722-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:10:36 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1872", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_d206d7f4712f430997740ed9c1cf4c08" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "4e853551ac5903d0", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:10:38.232Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_esbImy3vmBN4m7P5aPKyVpnZ", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_esbImy3vmBN4m7P5aPKyVpnZ" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"p9olw\"}", + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"SDk\"}", + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VxQdA\"}", + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"COrU\"}", + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"f\"}", + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"yNQ\"}", + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FqO7mw\"}", + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"T0BVU\"}", + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OHYcx\"}", + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7OpZTI\"}", + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"B\"}", + "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"svW0q8jYRz6x1Rg\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73bd18bc49722-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:10:38 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1445", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_902775bb729f4f03a8d4253d7714ea94" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:07.819Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-auto.cassette.json new file mode 100644 index 000000000..09af46693 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:08:57.204Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_jABav05m6Lh49u7RkhImjYSy\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Q4CbvtFAoVz2r\"}", + "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-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\":\"ZnxkjOco26\"}", + "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fx1pmjtV3\"}", + "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-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\":\"o0LoAIQm\"}", + "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xCbEvlVae\"}", + "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Wpb1msQouPe\"}", + "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-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\":\"3wSoQ4I2Ba\"}", + "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"GnC3ueVggWv\"}", + "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"GrbPwnnjKQIVBpo\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d739564fcfe899-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:08:57 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2098", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_7b1256885cb34d2dbda6fa00d5fd3804" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "2e6267c2dce30b4b", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:08:59.903Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_jABav05m6Lh49u7RkhImjYSy", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_jABav05m6Lh49u7RkhImjYSy" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vaNXP\"}", + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rvK\"}", + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DQary\"}", + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cRlo\"}", + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"T\"}", + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8dh\"}", + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4L0Et6\"}", + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JJdAs\"}", + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1dXPE\"}", + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Zr3Iwq\"}", + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"l\"}", + "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":275,\"total_tokens\":1362,\"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\":\"eth1YGg1e7w7nB9\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73965f810e899-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:08:59 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2333", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_838c74705b7f4845aa7821cf6c81625e" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:58.250Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-manual.cassette.json new file mode 100644 index 000000000..b87863e4d --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:08:45.133Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_kQeW1xF8fgmeZioc5LlwZGWr\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MN9hfnrsExyFa\"}", + "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-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\":\"FQNpAQzHQl\"}", + "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lc0hIZYm3\"}", + "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-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\":\"RqKIKB2b\"}", + "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8axETjVJZ\"}", + "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zZ6NfYPuqmH\"}", + "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-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\":\"5n0dn8y0wF\"}", + "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"DVS6lTWY4WY\"}", + "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"oKHDYxH060V1N2T\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d739081e44b121-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:08:45 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2581", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_4210eaf10c404b4f9c64dd69a765a040" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "aed2a20a04798f38", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:08:47.301Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_kQeW1xF8fgmeZioc5LlwZGWr", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_kQeW1xF8fgmeZioc5LlwZGWr" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Rnu16\"}", + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4HK\"}", + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"duVIF\"}", + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WEgS\"}", + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"C\"}", + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sGL\"}", + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"QdhybF\"}", + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1NXmS\"}", + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"v5e3b\"}", + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3wMD7l\"}", + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"z\"}", + "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"1k7k3G12D6wEi14\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d7391adb03b121-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:08:47 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1763", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_c1a4b521572344c1b91d487d80ca2429" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:57:56.285Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-auto.cassette.json new file mode 100644 index 000000000..37deabc4a --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:11:17.138Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_lohReHw4XtOerCHcrMH3HwSa\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wnZ3r3v4zQa7Z\"}", + "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-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\":\"DBjHaWkyI3\"}", + "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hKwrIRu86\"}", + "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-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\":\"EBqcfB5m\"}", + "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8b2GlTs5X\"}", + "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ck39zAsvYgS\"}", + "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-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\":\"qWtxajS9cA\"}", + "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"UogJT1L8VwQ\"}", + "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"d5WWCj5xETBhoYf\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73cc0e9e855e3-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:11:17 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2157", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_aae17bd7ccf84d9cada9b1e0f6083095" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "68fc442f7ad1940f", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:11:18.776Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_lohReHw4XtOerCHcrMH3HwSa", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_lohReHw4XtOerCHcrMH3HwSa" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"egDRK\"}", + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Nzo\"}", + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"N7YJJ\"}", + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6ujD\"}", + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"G\"}", + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"myI\"}", + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i8onRy\"}", + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"50Wk4\"}", + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mNPhI\"}", + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"W5OvrR\"}", + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"B\"}", + "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"gXCZDh1PnNtkH9E\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73cd05dad55e3-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:11:18 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1284", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_b6c41cb7368e4af8a3c6c328909c3701" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:14.012Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-manual.cassette.json new file mode 100644 index 000000000..1dc1e0ebb --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:11:05.329Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_lT5fESmP3VXujDrVhU0jTpWn\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JS6QLbfNLqRfu\"}", + "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-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\":\"g7ER5TS32f\"}", + "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FrGj4U9m9\"}", + "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-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\":\"G0i5xO14\"}", + "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gKHUnO7Uk\"}", + "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"K0YdpFdQGWm\"}", + "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-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\":\"PVxno9FqRH\"}", + "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"xv2OvDMmbOc\"}", + "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"XNv5acOEOwNlDTG\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73c745cef6711-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:11:05 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2588", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_9752b7a89b5f44619cbf60f353d9b1fd" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "e9732e8ff1f1d5f5", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:11:07.375Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_lT5fESmP3VXujDrVhU0jTpWn", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_lT5fESmP3VXujDrVhU0jTpWn" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"QkBF2\"}", + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eo9\"}", + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dMD6B\"}", + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HTLV\"}", + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"m\"}", + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sQl\"}", + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4QbbDy\"}", + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xYpUi\"}", + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vBtUv\"}", + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"frpkcP\"}", + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"s\"}", + "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"b9cDxkfDOhTnzNg\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73c869c156711-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:11:07 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1720", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_3d27ad56483a49769eb1a1fe52fe0da8" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:11.802Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-auto.cassette.json similarity index 87% rename from e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-auto.cassette.json rename to e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-auto.cassette.json index d3cdd11db..1bca5e4bf 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-auto.cassette.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-auto.cassette.json @@ -4,7 +4,7 @@ "callIndex": 0, "id": "02bfffc5f7e45fcc", "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-07-20T14:51:54.374Z", + "recordedAt": "2026-10-20T10:09:24.567Z", "request": { "body": { "kind": "json", @@ -268,15 +268,15 @@ "response": { "body": { "chunks": [ - "data: {\"id\":\"chatcmpl-E3jdQGseZWQcLrsgw93VodLi706J2\",\"object\":\"chat.completion.chunk\",\"created\":1784559112,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_WAf5AUNeoomo5nRHZF05YYu2\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2tovhZz8nyIwA\"}", - "data: {\"id\":\"chatcmpl-E3jdQGseZWQcLrsgw93VodLi706J2\",\"object\":\"chat.completion.chunk\",\"created\":1784559112,\"model\":\"gpt-5-nano-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\":\"bhRfQYMY6V\"}", - "data: {\"id\":\"chatcmpl-E3jdQGseZWQcLrsgw93VodLi706J2\",\"object\":\"chat.completion.chunk\",\"created\":1784559112,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"H1W1zAIpR\"}", - "data: {\"id\":\"chatcmpl-E3jdQGseZWQcLrsgw93VodLi706J2\",\"object\":\"chat.completion.chunk\",\"created\":1784559112,\"model\":\"gpt-5-nano-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\":\"d0JvUwDa\"}", - "data: {\"id\":\"chatcmpl-E3jdQGseZWQcLrsgw93VodLi706J2\",\"object\":\"chat.completion.chunk\",\"created\":1784559112,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OuxQlPCsx\"}", - "data: {\"id\":\"chatcmpl-E3jdQGseZWQcLrsgw93VodLi706J2\",\"object\":\"chat.completion.chunk\",\"created\":1784559112,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7I4BXwqVstQ\"}", - "data: {\"id\":\"chatcmpl-E3jdQGseZWQcLrsgw93VodLi706J2\",\"object\":\"chat.completion.chunk\",\"created\":1784559112,\"model\":\"gpt-5-nano-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\":\"UsygssD4Cd\"}", - "data: {\"id\":\"chatcmpl-E3jdQGseZWQcLrsgw93VodLi706J2\",\"object\":\"chat.completion.chunk\",\"created\":1784559112,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"5txPBCycfCU\"}", - "data: {\"id\":\"chatcmpl-E3jdQGseZWQcLrsgw93VodLi706J2\",\"object\":\"chat.completion.chunk\",\"created\":1784559112,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":152,\"total_tokens\":1194,\"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\":\"yjX19p3lyT8GxQV\"}", + "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_05rnLKgvxquWMWp01PoQH9QC\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"qLlyf7RH6Lbkz\"}", + "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-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\":\"tk64uzvkvg\"}", + "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cpFXscXZE\"}", + "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-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\":\"Z0VSOScd\"}", + "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Y4kiNcpdM\"}", + "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"J3mxBMduaIg\"}", + "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-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\":\"FJPblkHthi\"}", + "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"MUtJDCUHHJM\"}", + "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"HMb9OeeSNiVK1j7\"}", "data: [DONE]" ], "kind": "sse" @@ -285,18 +285,16 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "a1e2c9562ffd5ca1-IAD", - "connection": "keep-alive", + "cf-ray": "a4d739ffde1dbe3d-AMS", "content-type": "text/event-stream; charset=utf-8", - "date": "Mon, 20 Jul 2026 14:51:54 GMT", + "date": "Tue, 20 Oct 2026 10:09:24 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "1576", + "openai-processing-ms": "2389", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "transfer-encoding": "chunked", "x-content-type-options": "nosniff", "x-openai-proxy-wasm": "v0.1", "x-ratelimit-limit-requests": "30000", @@ -305,17 +303,16 @@ "x-ratelimit-remaining-tokens": "179999805", "x-ratelimit-reset-requests": "2ms", "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_824c4d66b14b401a80bf8e6ac6dfb030" + "x-request-id": "req_4c09d9a03464457d8eb2d57d3f1020dc" }, - "status": 200, - "statusText": "OK" + "status": 200 } }, { "callIndex": 1, - "id": "72f5fa1797c84800", + "id": "763d121cf819861f", "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-07-20T14:51:56.394Z", + "recordedAt": "2026-10-20T10:09:26.942Z", "request": { "body": { "kind": "json", @@ -338,7 +335,7 @@ "arguments": "{\"city\":\"Vienna\"}", "name": "lookup_weather" }, - "id": "call_WAf5AUNeoomo5nRHZF05YYu2", + "id": "call_05rnLKgvxquWMWp01PoQH9QC", "type": "function" } ] @@ -346,7 +343,7 @@ { "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", "role": "tool", - "tool_call_id": "call_WAf5AUNeoomo5nRHZF05YYu2" + "tool_call_id": "call_05rnLKgvxquWMWp01PoQH9QC" } ], "model": "gpt-5-nano", @@ -598,18 +595,18 @@ "response": { "body": { "chunks": [ - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7ixbG\"}", - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kfD\"}", - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1aym5\"}", - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"oDEn\"}", - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"X\"}", - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8V7\"}", - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LWoXnc\"}", - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DbemJ\"}", - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Fz0ek\"}", - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3ygAlq\"}", - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"X\"}", - "data: {\"id\":\"chatcmpl-E3jdSfRhSJA2nOXT8Icbjcjtz0K1x\",\"object\":\"chat.completion.chunk\",\"created\":1784559114,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":147,\"total_tokens\":1234,\"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\":\"fz7bIoP9tJSm74p\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Wq52t\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Wvr\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zKNYx\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HrMV\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"t\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"l8K\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9rmiCT\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k8yqu\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uAp7D\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZIjoaX\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"U\"}", + "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"ccMMEodguysW1M3\"}", "data: [DONE]" ], "kind": "sse" @@ -618,34 +615,31 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "a1e2c9612b495ca1-IAD", - "connection": "keep-alive", + "cf-ray": "a4d73a10ed6ebe3d-AMS", "content-type": "text/event-stream; charset=utf-8", - "date": "Mon, 20 Jul 2026 14:51:56 GMT", + "date": "Tue, 20 Oct 2026 10:09:26 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "1812", + "openai-processing-ms": "2004", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "transfer-encoding": "chunked", "x-content-type-options": "nosniff", "x-openai-proxy-wasm": "v0.1", "x-ratelimit-limit-requests": "30000", "x-ratelimit-limit-tokens": "180000000", "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-remaining-tokens": "179999787", "x-ratelimit-reset-requests": "2ms", "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_996dbc4535f44a298b86d81bcc75f03f" + "x-request-id": "req_a9f2c7b1c6ce4ccbaea288fa37250f26" }, - "status": 200, - "statusText": "OK" + "status": 200 } } ], "meta": { - "createdAt": "2026-07-20T14:51:56.619Z" + "createdAt": "2026-10-20T09:58:02.138Z" } } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-manual.cassette.json similarity index 87% rename from e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-manual.cassette.json rename to e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-manual.cassette.json index b6e03711f..c20961f0c 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-manual.cassette.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-manual.cassette.json @@ -4,7 +4,7 @@ "callIndex": 0, "id": "02bfffc5f7e45fcc", "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-07-20T14:51:40.635Z", + "recordedAt": "2026-10-20T10:09:11.569Z", "request": { "body": { "kind": "json", @@ -268,15 +268,15 @@ "response": { "body": { "chunks": [ - "data: {\"id\":\"chatcmpl-E3jdCRD2ZdXjpM0joLJxiTap2PYTn\",\"object\":\"chat.completion.chunk\",\"created\":1784559098,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_B5b5ExUj3UtB8q7ozaR2RcFh\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XEIiGtn1InYQM\"}", - "data: {\"id\":\"chatcmpl-E3jdCRD2ZdXjpM0joLJxiTap2PYTn\",\"object\":\"chat.completion.chunk\",\"created\":1784559098,\"model\":\"gpt-5-nano-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\":\"FknhY5rnVu\"}", - "data: {\"id\":\"chatcmpl-E3jdCRD2ZdXjpM0joLJxiTap2PYTn\",\"object\":\"chat.completion.chunk\",\"created\":1784559098,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vtkhNcZlp\"}", - "data: {\"id\":\"chatcmpl-E3jdCRD2ZdXjpM0joLJxiTap2PYTn\",\"object\":\"chat.completion.chunk\",\"created\":1784559098,\"model\":\"gpt-5-nano-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\":\"vMt5jEko\"}", - "data: {\"id\":\"chatcmpl-E3jdCRD2ZdXjpM0joLJxiTap2PYTn\",\"object\":\"chat.completion.chunk\",\"created\":1784559098,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FFP6W0KNT\"}", - "data: {\"id\":\"chatcmpl-E3jdCRD2ZdXjpM0joLJxiTap2PYTn\",\"object\":\"chat.completion.chunk\",\"created\":1784559098,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7oWJEwQWZVS\"}", - "data: {\"id\":\"chatcmpl-E3jdCRD2ZdXjpM0joLJxiTap2PYTn\",\"object\":\"chat.completion.chunk\",\"created\":1784559098,\"model\":\"gpt-5-nano-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\":\"KW01qh0PNy\"}", - "data: {\"id\":\"chatcmpl-E3jdCRD2ZdXjpM0joLJxiTap2PYTn\",\"object\":\"chat.completion.chunk\",\"created\":1784559098,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"12KTjMtL8HI\"}", - "data: {\"id\":\"chatcmpl-E3jdCRD2ZdXjpM0joLJxiTap2PYTn\",\"object\":\"chat.completion.chunk\",\"created\":1784559098,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":408,\"total_tokens\":1450,\"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\":\"B8HBw8SlSXErNSJ\"}", + "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_zj47kW1OmTDg9KT3LzNnBFFZ\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JPNieEQLpGOOa\"}", + "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-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\":\"qcfcpUyvFd\"}", + "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"okRrk8hLu\"}", + "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-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\":\"fn9PVIdT\"}", + "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Ci6B9ZIvF\"}", + "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5QbUYN5mc2K\"}", + "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-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\":\"bRqyP6SXYu\"}", + "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"xMgMd2vQ9bs\"}", + "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"JOwJdz9fJxRYNXw\"}", "data: [DONE]" ], "kind": "sse" @@ -285,18 +285,16 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "a1e2c8f8bf98d860-IAD", - "connection": "keep-alive", + "cf-ray": "a4d739a93b254547-AMS", "content-type": "text/event-stream; charset=utf-8", - "date": "Mon, 20 Jul 2026 14:51:40 GMT", + "date": "Tue, 20 Oct 2026 10:09:11 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "2698", + "openai-processing-ms": "3255", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "transfer-encoding": "chunked", "x-content-type-options": "nosniff", "x-openai-proxy-wasm": "v0.1", "x-ratelimit-limit-requests": "30000", @@ -305,17 +303,16 @@ "x-ratelimit-remaining-tokens": "179999802", "x-ratelimit-reset-requests": "2ms", "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_d111d16fb6e647a190d222ba7215b58e" + "x-request-id": "req_c03f2314b59049e89f0c5ead3716f7c7" }, - "status": 200, - "statusText": "OK" + "status": 200 } }, { "callIndex": 1, - "id": "888ecd04b50ae481", + "id": "b09994c47237c61a", "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-07-20T14:51:42.667Z", + "recordedAt": "2026-10-20T10:09:13.889Z", "request": { "body": { "kind": "json", @@ -338,7 +335,7 @@ "arguments": "{\"city\":\"Vienna\"}", "name": "lookup_weather" }, - "id": "call_B5b5ExUj3UtB8q7ozaR2RcFh", + "id": "call_zj47kW1OmTDg9KT3LzNnBFFZ", "type": "function" } ] @@ -346,7 +343,7 @@ { "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", "role": "tool", - "tool_call_id": "call_B5b5ExUj3UtB8q7ozaR2RcFh" + "tool_call_id": "call_zj47kW1OmTDg9KT3LzNnBFFZ" } ], "model": "gpt-5-nano", @@ -598,18 +595,18 @@ "response": { "body": { "chunks": [ - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"c6Ldt\"}", - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"M8y\"}", - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nrAXw\"}", - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k8TL\"}", - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"O\"}", - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7Ch\"}", - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"B6awI3\"}", - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Vzybo\"}", - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pLg3X\"}", - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uSFWLq\"}", - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"k\"}", - "data: {\"id\":\"chatcmpl-E3jdFRXsUNgVqL3xX7fwggT9H1eHI\",\"object\":\"chat.completion.chunk\",\"created\":1784559101,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"Kb0608Kpte5vdnr\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"U2Qac\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"adM\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FiBDS\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Rc6r\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"w\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"x9O\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xf9jCL\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"n5ljI\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"yqcfk\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gGhewn\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"H\"}", + "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"STqgtrMLFEWIDz1\"}", "data: [DONE]" ], "kind": "sse" @@ -618,34 +615,31 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "a1e2c90b595ed860-IAD", - "connection": "keep-alive", + "cf-ray": "a4d739bf8c984547-AMS", "content-type": "text/event-stream; charset=utf-8", - "date": "Mon, 20 Jul 2026 14:51:42 GMT", + "date": "Tue, 20 Oct 2026 10:09:13 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "1803", + "openai-processing-ms": "1986", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "transfer-encoding": "chunked", "x-content-type-options": "nosniff", "x-openai-proxy-wasm": "v0.1", "x-ratelimit-limit-requests": "30000", "x-ratelimit-limit-tokens": "180000000", "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-remaining-tokens": "179999790", "x-ratelimit-reset-requests": "2ms", "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_86fd123f746047a3be732d88d5d2adbc" + "x-request-id": "req_916eb093a8664a6aaec5ccf24cae6b23" }, - "status": 200, - "statusText": "OK" + "status": 200 } } ], "meta": { - "createdAt": "2026-07-20T14:51:42.895Z" + "createdAt": "2026-10-20T09:57:59.945Z" } } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-auto.cassette.json new file mode 100644 index 000000000..d286ce40d --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:11:45.781Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_AjsrstVScciOwtnGzG1bLURZ\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1xx7dntXxxATh\"}", + "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-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\":\"yZ0zdY1xob\"}", + "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EUZ47I75n\"}", + "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-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\":\"efM0C30T\"}", + "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3vL9MR2q4\"}", + "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0FRuwhEnAk6\"}", + "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-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\":\"F5iGxERxBv\"}", + "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"pBYJBBE7IUm\"}", + "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":408,\"total_tokens\":1450,\"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\":\"GfeepGrcWcMYRXV\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73d6a7f78468e-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:11:45 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3627", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_8167fa423a1c4d25815830ceecdd187e" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "c10008cbbbfbe9ad", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:11:49.000Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_AjsrstVScciOwtnGzG1bLURZ", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_AjsrstVScciOwtnGzG1bLURZ" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OZ5K6\"}", + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZKn\"}", + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"S1zTf\"}", + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"o1WC\"}", + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6\"}", + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Ont\"}", + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"j9sMNn\"}", + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TNUxz\"}", + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YHnol\"}", + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5QKQUL\"}", + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"F\"}", + "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"HVu969gaybLBubf\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73d861bca468e-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:11:48 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2374", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_ad4ebbe9072c4513ba103942f2685448" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:17.191Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-manual.cassette.json new file mode 100644 index 000000000..a55745ba4 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:11:29.907Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_JFr0p7MGmQ19j4n7inLZXR8a\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rC8IwdM9tKFoe\"}", + "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-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\":\"itaWdVXOB0\"}", + "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MAM8403Ra\"}", + "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-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\":\"KXeq6vub\"}", + "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XlSOI9DjF\"}", + "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"q9shWpUvglh\"}", + "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-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\":\"zvTkhWRcL4\"}", + "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"SZBkt3FiLiJ\"}", + "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"iobg6ptimpWpwZz\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73d120aab299d-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:11:29 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1968", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_a9ab06a4a51f457bbac3b8081536cd73" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "1a13e8e2362f738d", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:11:31.781Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_JFr0p7MGmQ19j4n7inLZXR8a", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_JFr0p7MGmQ19j4n7inLZXR8a" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0YshI\"}", + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Udc\"}", + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"QbFdo\"}", + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kz9J\"}", + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"e\"}", + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ADB\"}", + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"AckZ2r\"}", + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hhpBm\"}", + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hMmBD\"}", + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pqCSQG\"}", + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"d\"}", + "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"jHUhEb29GuMgD7B\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73d2048f5299d-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:11:31 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1546", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_9fae578248f940b593221263ad0b142d" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:15.734Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-auto.cassette.json new file mode 100644 index 000000000..754cfb68d --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:09:52.206Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_ZLXVzLQC0SzSI7FsZYSKLMnQ\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"631lclTyYKemI\"}", + "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-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\":\"A855RJWli0\"}", + "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jEpIV3ini\"}", + "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-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\":\"yKWn5gET\"}", + "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1KGWQLyDi\"}", + "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"buRpsYxkYrR\"}", + "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-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\":\"p1V02VQSfg\"}", + "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"LuxP9RjexbM\"}", + "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"mbC8uLjqT0OmYLj\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73aa99849bb22-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:09:52 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2698", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_94bca2a7f78241b2831931fdeb62ab6f" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "311c6a2fd44939ec", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:09:52.895Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_ZLXVzLQC0SzSI7FsZYSKLMnQ", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_ZLXVzLQC0SzSI7FsZYSKLMnQ" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VnC8v\"}", + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"52n\"}", + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mvI4p\"}", + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bq55\"}", + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"V\"}", + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jUn\"}", + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"63CDgY\"}", + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Z1bGg\"}", + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Uc5Ga\"}", + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"g0VpEv\"}", + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"p\"}", + "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":12,\"total_tokens\":1099,\"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\":\"TS\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73abd999fbb22-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:09:52 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "280", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_a35833937a21462c80c32bb2b8fbec8a" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:58:05.817Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-manual.cassette.json new file mode 100644 index 000000000..7f5ae75de --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:09:39.019Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_gkptEKyJ8ZngBCtQEFPv5BQN\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DYQh6pqPSia94\"}", + "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-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\":\"BlfxWZULiD\"}", + "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EH9cwKpp5\"}", + "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-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\":\"EjY3AYk2\"}", + "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i6e3JhT4R\"}", + "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LID0DcPchFP\"}", + "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-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\":\"9eD7CxvEnK\"}", + "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"p5UKkmVLRjx\"}", + "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"0m9FC7l0AJu9I52\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73a5a5b601afc-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:09:38 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2340", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_db21f254ca0c431aad116674d5d33c5b" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "ad1633ea607ec71a", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:09:40.828Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_gkptEKyJ8ZngBCtQEFPv5BQN", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_gkptEKyJ8ZngBCtQEFPv5BQN" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1Wi3C\"}", + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"F7R\"}", + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0QQS2\"}", + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PbAl\"}", + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k\"}", + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1Hk\"}", + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZYEeXH\"}", + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5GSac\"}", + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HRC97\"}", + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cNsDLf\"}", + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"P\"}", + "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"rt9rqyfnMrPs7T0\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73a6b3c721afc-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:09:40 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1451", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_951c8acac8b64684a1083509ef217389" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:58:03.857Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-auto.cassette.json new file mode 100644 index 000000000..52cf64ae2 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:12:16.459Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_kFKeDv4lIYCw8RR74P4ypMWa\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"SsLQh4hbuGqTz\"}", + "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-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\":\"9DrX7nJw3C\"}", + "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MOjN8kEaP\"}", + "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-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\":\"mTSc1OU8\"}", + "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8FJzhhcmj\"}", + "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Ua1DSLfA2O3\"}", + "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-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\":\"aAMR0n8U2k\"}", + "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"2SRIjQ5YUc3\"}", + "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"qSN96trdObwVrxF\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73e299cd87104-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:12:16 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3761", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_a95cb34d3887485b99841653d390f4ba" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "e59ad52e00aa8bdb", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:12:18.748Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_kFKeDv4lIYCw8RR74P4ypMWa", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_kFKeDv4lIYCw8RR74P4ypMWa" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bO4qQ\"}", + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RH8\"}", + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HRPMC\"}", + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ilCE\"}", + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6\"}", + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2Qg\"}", + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9ktwFd\"}", + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hewTT\"}", + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"d2ulO\"}", + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FM4Tn3\"}", + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"Q\"}", + "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"BCnPuWvALxguxfH\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73e431eeb7104-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:12:18 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1838", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_6c149c3f0b8944deb737d3a395698c14" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:21.070Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-manual.cassette.json new file mode 100644 index 000000000..158295a13 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:12:02.602Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_mI4h5t6atpk9C2yVVRj8zvmX\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TbkirGcwrjuXh\"}", + "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-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\":\"CJ0aad7IEN\"}", + "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"a9o01YcH4\"}", + "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-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\":\"mHmPPBzh\"}", + "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Uye2fDY7k\"}", + "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eYkGfp2djBD\"}", + "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-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\":\"zO6kzxSpJj\"}", + "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"c8OCvX6iwsx\"}", + "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"Mwfe3aqKPY8gljS\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73dc8ee420692-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:12:02 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "5367", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_43a03d16c66c4fe7803da15adc8a2e0b" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "4cc58523f7bd569e", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:12:05.285Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_mI4h5t6atpk9C2yVVRj8zvmX", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_mI4h5t6atpk9C2yVVRj8zvmX" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zyiwf\"}", + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Np3\"}", + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WvFZ7\"}", + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"A7ez\"}", + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k\"}", + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gSr\"}", + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"IJT194\"}", + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JmOH1\"}", + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"E060D\"}", + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Wqdh3j\"}", + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"A\"}", + "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"qe9U4vMPCHwnKoO\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73dec98930692-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:12:05 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2238", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_60777dc44f3a44ffb00ab8367cb91dc4" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:18.851Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-auto.cassette.json new file mode 100644 index 000000000..739e696df --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:58:33.178Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_B92ELFZUBDMFNiz7o9of9Be5\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Zf9BZExL6vKYE\"}", + "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-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\":\"KQ4RQm6UpF\"}", + "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fccCb7RAu\"}", + "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-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\":\"x28GVZU7\"}", + "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dfLAzIekj\"}", + "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fXQYz03cfcm\"}", + "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-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\":\"YAcmUpNQDc\"}", + "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"XgfrNR79JOs\"}", + "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":281,\"total_tokens\":1323,\"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\":\"hgKjYW444ANuKUV\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72a0f48ac77ce-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:58:33 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3685", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_fc1c5626ef42417a9e1e2f8e6ee83c31" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "3166ad067546fc91", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:58:38.064Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_B92ELFZUBDMFNiz7o9of9Be5", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_B92ELFZUBDMFNiz7o9of9Be5" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EfQV1\"}", + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ttz\"}", + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MeJFg\"}", + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"T54j\"}", + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4\"}", + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wnA\"}", + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"juAzJ3\"}", + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"BI1m0\"}", + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"IShII\"}", + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"qhXje8\"}", + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"8\"}", + "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":338,\"total_tokens\":1425,\"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\":\"Bsa3DSPwgKF18qc\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72a298b7e77ce-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:58:37 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "4293", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_d855d615f5f94f88918f502dc4742ca8" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:58:38.197Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-manual.cassette.json new file mode 100644 index 000000000..314b85f27 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:58:18.644Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_HHjjGv2LdPcgB7EVXaFgTARg\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WRsxm6Ytwi5DB\"}", + "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-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\":\"xQCJqJ0KaM\"}", + "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"P1bLmKzSj\"}", + "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-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\":\"YMfmSVmT\"}", + "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lr28Eh3C8\"}", + "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"m3J92MXyhgO\"}", + "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-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\":\"6hA6DxbAfd\"}", + "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"G5PH4p9liMM\"}", + "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":408,\"total_tokens\":1450,\"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\":\"ELUegqYM4hp64t1\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d729a94b2eef92-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:58:18 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "5219", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_9fabd6096e6c47fabf2ab837d020e440" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "4445ee4074946e89", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:58:22.944Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_HHjjGv2LdPcgB7EVXaFgTARg", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_HHjjGv2LdPcgB7EVXaFgTARg" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DJSm6\"}", + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"a5E\"}", + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ISMb1\"}", + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fkAj\"}", + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1\"}", + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bFm\"}", + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"oGPpEo\"}", + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"p59vQ\"}", + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"qMUNc\"}", + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k14v2V\"}", + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"O\"}", + "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"vugfCzMGCuRlS2m\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d729cebf28ef92-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:58:22 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3730", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_44a151b3b71142ec94cac60eb89324e1" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:58:23.081Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-auto.cassette.json new file mode 100644 index 000000000..d5f339be8 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:00:45.391Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_5ThZtti5bEpO335tNVLh3ZBe\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LZr2sZVl1Af6O\"}", + "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-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\":\"6POlRsXFmP\"}", + "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8kLNoq7Ve\"}", + "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-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\":\"eF9RrhnZ\"}", + "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"iJHUlg9LF\"}", + "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"15s8KaA7khX\"}", + "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-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\":\"SUkPqz7uzo\"}", + "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"iUajhw7cfP9\"}", + "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"A8kLCVI47CaMncN\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72d4a7bffdef8-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:00:45 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3749", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_bc42528bacb741d0b29fd4363e37c9fe" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "55c957cb1e2795e6", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:00:47.759Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_5ThZtti5bEpO335tNVLh3ZBe", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_5ThZtti5bEpO335tNVLh3ZBe" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jiFHK\"}", + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"A18\"}", + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1O6OS\"}", + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xOL7\"}", + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"O\"}", + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3Dn\"}", + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JLDEQU\"}", + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eFpMS\"}", + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4su7W\"}", + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5dAaqF\"}", + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"a\"}", + "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"DH1jlrspoGo1y4Z\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72d63e823def8-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:00:47 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2016", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_bb17794dcecb46a891c68c49d2f8f9df" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:47.878Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-manual.cassette.json new file mode 100644 index 000000000..76e856338 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:00:31.918Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_sdfZISOxvrCHLIK3nj4uAWDn\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"veuc3a88S5P4u\"}", + "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-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\":\"LtM8c0zf7X\"}", + "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pntQ6lLGx\"}", + "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-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\":\"KMW2p7Vb\"}", + "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"To3ZZT1p0\"}", + "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"aK9DS47hsM5\"}", + "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-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\":\"fGoENuMr3g\"}", + "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"MKkfpokVGND\"}", + "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"bgAK3DExweRI4vg\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72cfb99997d58-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:00:31 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2846", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_db7bef2024e0488b90c607ce431d0ad1" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "7dacb235cbcab544", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:00:35.100Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_sdfZISOxvrCHLIK3nj4uAWDn", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_sdfZISOxvrCHLIK3nj4uAWDn" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"IKAL0\"}", + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bBT\"}", + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Bctwm\"}", + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9OmN\"}", + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"f\"}", + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vDH\"}", + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jsLkII\"}", + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"A7OGa\"}", + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YSyhF\"}", + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"GYeyEw\"}", + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"M\"}", + "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"Xi46tCbEt3I9mhP\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72d0fcbda7d58-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:00:34 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2816", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_cc3cd879a1884cacba4e9a64329ce1b8" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:00:35.239Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-auto.cassette.json new file mode 100644 index 000000000..a53e8b42c --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:59:03.438Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_xNQDpoCwxAHn5JpQnTDFKN7D\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OsI72d23b8dsl\"}", + "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-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\":\"p7ZEGd2Nxt\"}", + "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"R74UXTvZY\"}", + "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-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\":\"HOfRyBTx\"}", + "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"glkLlom1P\"}", + "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3SgBgDFqj8m\"}", + "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-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\":\"HHWZA5W7r7\"}", + "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"GvyWLUjJpIR\"}", + "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"YynEPXl8DbdPas2\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72ace2a3b9e98-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:59:03 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3657", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_fc077af23d3d45a3b9f3d67c553d3477" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "68ba75ee7f10582d", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:59:06.375Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_xNQDpoCwxAHn5JpQnTDFKN7D", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_xNQDpoCwxAHn5JpQnTDFKN7D" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HhoUE\"}", + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nqH\"}", + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cLLDv\"}", + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tGcg\"}", + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"s\"}", + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"f5K\"}", + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KR9T1d\"}", + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5GuSh\"}", + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"GGKtH\"}", + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fD75Xc\"}", + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"B\"}", + "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"9a0vyyw83brBOaU\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72ae6a8289e98-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:59:06 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2614", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_dcaebf223fa24a949cdcae038402bf8d" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:59:06.494Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-manual.cassette.json new file mode 100644 index 000000000..b5f6b6b89 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:58:49.747Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_6OYjiftKSop9X0JZBh3SMChY\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rsEgCh1Fpsb9F\"}", + "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-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\":\"dGEXGIjoXm\"}", + "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"AnxSwXi8q\"}", + "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-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\":\"VTKCiC8U\"}", + "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"prPUskntf\"}", + "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hMbRv4fmEQ2\"}", + "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-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\":\"8ZY4kd98P7\"}", + "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"rMcq4iofjV5\"}", + "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":472,\"total_tokens\":1514,\"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\":\"j4R2vB6fVrgmVyk\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72a727a159eb5-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:58:49 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "4569", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_5d1851cf0d4f42978a22780cec8c96a2" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "4d6ab7b6eb37b3cd", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:58:52.724Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_6OYjiftKSop9X0JZBh3SMChY", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_6OYjiftKSop9X0JZBh3SMChY" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"U3FV2\"}", + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Yk3\"}", + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"aQJlG\"}", + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"By88\"}", + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i\"}", + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KrI\"}", + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OgLho1\"}", + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YEcoO\"}", + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Irlul\"}", + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0cBwBW\"}", + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"D\"}", + "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"MsINEI6yT0tHGmI\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72a911b949eb5-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:58:52 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2630", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_e2a03ee70355439ba4b688d71e8c76e9" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:58:52.848Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-auto.cassette.json new file mode 100644 index 000000000..67eed5719 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:01:11.209Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_lrj5Nqvby8KWXiUtzjpGUVj5\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dXzrxsIZSgwqr\"}", + "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-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\":\"HZiKdgBmcf\"}", + "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1PAwWW5Kl\"}", + "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-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\":\"AzMcTOHG\"}", + "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pN4iLQ2Dt\"}", + "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zIeqXQsYL42\"}", + "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-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\":\"oYhuxfOmQQ\"}", + "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"U48e9G8TV1W\"}", + "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"eD2Ot0C0xULTjSL\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72df51e3bd6c6-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:01:11 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2250", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_e39430c2f1494f8d8da1c0eeb0d19901" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "ae787b957a109732", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:01:13.154Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_lrj5Nqvby8KWXiUtzjpGUVj5", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_lrj5Nqvby8KWXiUtzjpGUVj5" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TQ0tk\"}", + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"x1r\"}", + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wCe0N\"}", + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"IVJQ\"}", + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"D\"}", + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"BVg\"}", + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PNrmZj\"}", + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"e2QF4\"}", + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ANdWJ\"}", + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RSY7yZ\"}", + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"9\"}", + "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"MYpTrBpzxB7EnV5\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72e053976d6c6-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:01:13 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1614", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_ee22b7f29169480e8e3f494d80fd7d60" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:01:13.237Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-manual.cassette.json new file mode 100644 index 000000000..38974b260 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:00:59.075Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_gVUqolvEY2uCJGuSogRdM2Br\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nzuITc8DqPqhF\"}", + "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-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\":\"yvmoSlqMCx\"}", + "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WWzlCdrpC\"}", + "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-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\":\"CXUptTeS\"}", + "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FNhQoiBj3\"}", + "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ICMGGKiwf4P\"}", + "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-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\":\"rc3zxDlZVh\"}", + "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"a44eOXY5SPG\"}", + "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"jlP36LC4Rxvr51h\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72da1bddebb01-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:00:58 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3322", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_2f8cf14bab0948149ebfe92b3ac79a34" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "268b6df74db78fd4", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:01:01.780Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_gVUqolvEY2uCJGuSogRdM2Br", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_gVUqolvEY2uCJGuSogRdM2Br" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wl1Ys\"}", + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vrv\"}", + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Ow86d\"}", + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"yRKa\"}", + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"D\"}", + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gKh\"}", + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MZSMa8\"}", + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"SZidJ\"}", + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pmRTY\"}", + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hRD5p3\"}", + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"7\"}", + "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"eAkdWesEoaihAhr\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72db97933bb01-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:01:01 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2384", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_ae74e3e5b2024b54b20af441679381e0" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:01:01.949Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-auto.cassette.json new file mode 100644 index 000000000..fe1145f80 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:59:29.818Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_sHA0ZF1N8ggjtSHC4gZLeFdY\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MFkcxRMobvh6F\"}", + "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-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\":\"ynY64PDaTc\"}", + "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i9vyIaVc6\"}", + "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-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\":\"OcU62bdw\"}", + "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4iahNzPKr\"}", + "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tmjoCzyWOC2\"}", + "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-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\":\"iFOSaOejBu\"}", + "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"TOmpn4lEBhJ\"}", + "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"HRx8jVyRRCBrWib\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72b7ddc63d139-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:59:29 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1797", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_33daadefa5c041b3bd7ec685a6d5b4df" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "59950cb3e1c739df", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:59:31.692Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_sHA0ZF1N8ggjtSHC4gZLeFdY", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_sHA0ZF1N8ggjtSHC4gZLeFdY" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"s1K6v\"}", + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"K4w\"}", + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tx7fX\"}", + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"om07\"}", + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7\"}", + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"qsF\"}", + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fZsefr\"}", + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k5wgC\"}", + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pl15Q\"}", + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DSncSl\"}", + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"V\"}", + "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"GVv1KwGYssvl0wt\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72b8b8b3bd139-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:59:31 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1589", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_78ad9c5a40054556a8df03c6775e3b2c" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:59:31.890Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-manual.cassette.json new file mode 100644 index 000000000..12f0c416f --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:59:18.191Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_IFUh6njYa64NPUYhaTZVYYa2\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EkjBJTFGVyyaV\"}", + "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-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\":\"K4kWRn2DQZ\"}", + "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HoPh1MMrs\"}", + "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-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\":\"BSIhYzuD\"}", + "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"NXrEaMbmx\"}", + "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xquKnOMPR5L\"}", + "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-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\":\"yqovgW3eAt\"}", + "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"nmbaJ7g2fFg\"}", + "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"AScx6UciXJDjmgm\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72b251c999e8b-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:59:18 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "4437", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999802", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_739e35a8481641fab4ac633d156ce895" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "beab81f7a9f98a84", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:59:19.856Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_IFUh6njYa64NPUYhaTZVYYa2", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_IFUh6njYa64NPUYhaTZVYYa2" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sKwTX\"}", + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"UN7\"}", + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TSlxd\"}", + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"aAca\"}", + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"e\"}", + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wi8\"}", + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8nyT61\"}", + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"BCA0j\"}", + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YD6zX\"}", + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FXajZu\"}", + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"i\"}", + "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":82,\"total_tokens\":1169,\"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\":\"p\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72b42dd109e8b-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:59:19 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1348", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_f419844b3f28413596495edc96dd0b02" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:59:20.029Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-auto.cassette.json new file mode 100644 index 000000000..08b1405f0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:01:34.587Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_D7yq9HLW6poTZQJIJMWkODSa\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wakut9liTY0zA\"}", + "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-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\":\"k32X95yHoW\"}", + "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3jVn1lGIj\"}", + "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-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\":\"0zLFTODm\"}", + "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"AvM1Mi6XO\"}", + "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cadKaNPcFNN\"}", + "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-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\":\"HBEr4whRSs\"}", + "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"V6BrprleCZO\"}", + "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"8QR7M9UnvAGtAAM\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72e838a529f94-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:01:34 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2807", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_731100964494444fad25911a06fcf14f" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "c9d6d5bdf521c768", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:01:36.762Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_D7yq9HLW6poTZQJIJMWkODSa", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_D7yq9HLW6poTZQJIJMWkODSa" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"b5TFp\"}", + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3Qf\"}", + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"X7oc8\"}", + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3cvy\"}", + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"n\"}", + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7e7\"}", + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zy6Eh5\"}", + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"U4TmD\"}", + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"yN8d6\"}", + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vYAaqi\"}", + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"b\"}", + "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"0nRgZl4KBRhH2UE\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72e9759df9f94-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:01:36 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1779", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_485a795b7020444390a7df2b40d4d41f" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:01:36.871Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-manual.cassette.json new file mode 100644 index 000000000..d23513742 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:01:21.869Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_4dS6X4hDlMFjzMyFSzs9wkqO\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5BOHZWfcA4vDE\"}", + "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-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\":\"4aphV34ifQ\"}", + "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pShGIfBCX\"}", + "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-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\":\"78ploexT\"}", + "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PIxRM7ekA\"}", + "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7b6VeTZQAdl\"}", + "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-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\":\"Vv1BXFloaA\"}", + "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"J6kIwyBUbYn\"}", + "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"Yd0YEkmW7wDkeww\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72e369a876f02-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:01:21 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2427", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_2d926e759f044bffb6b719b1e8bc606b" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "e3b6da80f41e42f4", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:01:24.318Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_4dS6X4hDlMFjzMyFSzs9wkqO", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_4dS6X4hDlMFjzMyFSzs9wkqO" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"a3TF3\"}", + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Eh1\"}", + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Pgq46\"}", + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Bksl\"}", + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"m\"}", + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"l5U\"}", + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3ygjNu\"}", + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"U1rqE\"}", + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4Wnoi\"}", + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zUi7Mo\"}", + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"k\"}", + "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"ZX95IcgMBi2vEN9\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72e47ea0c6f02-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:01:24 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2113", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_7a48c3c202f24a0195ced2e4de317df3" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:01:24.505Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-auto.cassette.json new file mode 100644 index 000000000..85132c76f --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:59:55.268Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_85JS44Bbc6rjWTaZNzg37YXt\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fuzjgkEsYNIKJ\"}", + "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-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\":\"L1svs1Wuvf\"}", + "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hgaoqyTKe\"}", + "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-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\":\"bkPTeFQK\"}", + "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DOPQlNzaT\"}", + "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"58aWp1aLHMv\"}", + "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-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\":\"2WLQIA8kVd\"}", + "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"jWsfGT11iHD\"}", + "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"PUXUM7bxVWsT4eZ\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72c10bc4f9a38-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:59:55 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3822", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_433053277142468bb88ff5e25189940e" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "7f4dc829bbd90154", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:59:56.987Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_85JS44Bbc6rjWTaZNzg37YXt", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_85JS44Bbc6rjWTaZNzg37YXt" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"R5ck4\"}", + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Pbz\"}", + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jzSxf\"}", + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VSBZ\"}", + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2\"}", + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0gV\"}", + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"oI577Q\"}", + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uqdit\"}", + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TJAIC\"}", + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tPZKzy\"}", + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"Y\"}", + "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":82,\"total_tokens\":1169,\"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\":\"7\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72c2a991b9a38-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:59:56 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1339", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_b5009b5b607e463b80ba9f0cf909ac1c" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:59:57.125Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-manual.cassette.json new file mode 100644 index 000000000..96c5904f8 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:59:42.964Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_v7WaQrLFlbVaAvbi2LyCY01Z\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"O41qHcfRURikH\"}", + "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-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\":\"jfzg3RpkPt\"}", + "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WZ5keexCZ\"}", + "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-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\":\"gal5CMtm\"}", + "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vbEC5MCIV\"}", + "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jj8XV3DN4z0\"}", + "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-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\":\"CYBpD88jyz\"}", + "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"gQ1DCP8ERZP\"}", + "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":281,\"total_tokens\":1323,\"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\":\"Z2AyUwc4bCjqEvd\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72bca7a1c7e8f-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:59:42 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2735", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_0017634ea14c4d139b50dce893515714" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "56bbc404048cb24f", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T09:59:43.812Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_v7WaQrLFlbVaAvbi2LyCY01Z", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_v7WaQrLFlbVaAvbi2LyCY01Z" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k5wX7\"}", + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xMh\"}", + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"iJXnF\"}", + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"NVqA\"}", + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"O\"}", + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Dy9\"}", + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Lzx3QD\"}", + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"N4sld\"}", + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LiyIU\"}", + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EjIqR0\"}", + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"z\"}", + "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":12,\"total_tokens\":1099,\"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\":\"fN\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72bddbaec7e8f-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 09:59:43 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "266", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_9c22de530acf4a4b951c695f9d04c877" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:59:43.985Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-auto.cassette.json new file mode 100644 index 000000000..e21a7d8a0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:02:01.541Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_pKyBLhpNnk0up8OzqLvokeGn\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LXN46ZyOs5JRN\"}", + "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-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\":\"XqmaQqkNUi\"}", + "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"L9m3cxh6k\"}", + "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-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\":\"xhFICKFU\"}", + "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"C6kvPZtZl\"}", + "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2xnjy0uHnD5\"}", + "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-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\":\"K1UB5alHdG\"}", + "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"YqN9z43JhO5\"}", + "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"NRCaj8PM3ctXMz8\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72f2cf83dff34-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:02:01 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2682", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_0f2e9de7d8f144b2865be460c8341cb7" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "f58bfb7fba7a8fa5", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:02:03.666Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_pKyBLhpNnk0up8OzqLvokeGn", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_pKyBLhpNnk0up8OzqLvokeGn" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dL0x1\"}", + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YXu\"}", + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XAvua\"}", + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"r8Cu\"}", + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"s\"}", + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kBJ\"}", + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"SfzBhA\"}", + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Fb5s4\"}", + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4qBHe\"}", + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"x24IJR\"}", + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"n\"}", + "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"sl2z5HWbhzrHbiK\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72f4049ecff34-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:02:03 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1654", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_80d70c81490a4c9684d44b948be1de45" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:02:03.878Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-manual.cassette.json new file mode 100644 index 000000000..4b3a095af --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:01:46.787Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_lxSYIpPRyMC659O73xCA1f7P\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zgeyx3HrTZPOY\"}", + "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-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\":\"Elq2OcWWTa\"}", + "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lipp2Ebfo\"}", + "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-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\":\"gys5mBrD\"}", + "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2xHA4C41y\"}", + "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tCrBKNP50so\"}", + "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-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\":\"Ozu3YhiPix\"}", + "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"DnZlDGqqHWa\"}", + "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"liapAZtlEatVUXw\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72ed2cc40b192-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:01:46 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2382", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_93bfa6a57b5a4600ad3f5fa2707686ac" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "e9e0dd47a4155fd1", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:01:49.097Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_lxSYIpPRyMC659O73xCA1f7P", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_lxSYIpPRyMC659O73xCA1f7P" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uH8K2\"}", + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k0U\"}", + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uyyto\"}", + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bJ8B\"}", + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"F\"}", + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"R95\"}", + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZmIauS\"}", + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"V1g8w\"}", + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YRddJ\"}", + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0rO5kJ\"}", + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"V\"}", + "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"Sjur7aPJ10OgEWl\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72ee73d7eb192-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:01:48 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1400", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_ea8607cc68614ff599d4df16f246d4b9" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:01:49.697Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-1-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-1-ai7-auto.cassette.json new file mode 100644 index 000000000..2421a71e0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-1-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:03:32.432Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0yms5JkEXzin8l8b8B8aSzAnUEw\",\"object\":\"chat.completion.chunk\",\"created\":1792490608,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_VAz37DGPQjMeg7dwEPebWead\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jDzZX8CeOsCk1\"}", + "data: {\"id\":\"chatcmpl-Eb0yms5JkEXzin8l8b8B8aSzAnUEw\",\"object\":\"chat.completion.chunk\",\"created\":1792490608,\"model\":\"gpt-5-nano-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\":\"t0VgXaG8fe\"}", + "data: {\"id\":\"chatcmpl-Eb0yms5JkEXzin8l8b8B8aSzAnUEw\",\"object\":\"chat.completion.chunk\",\"created\":1792490608,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RGq5BMft7\"}", + "data: {\"id\":\"chatcmpl-Eb0yms5JkEXzin8l8b8B8aSzAnUEw\",\"object\":\"chat.completion.chunk\",\"created\":1792490608,\"model\":\"gpt-5-nano-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\":\"wCzjDJYw\"}", + "data: {\"id\":\"chatcmpl-Eb0yms5JkEXzin8l8b8B8aSzAnUEw\",\"object\":\"chat.completion.chunk\",\"created\":1792490608,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Qd0kshwMy\"}", + "data: {\"id\":\"chatcmpl-Eb0yms5JkEXzin8l8b8B8aSzAnUEw\",\"object\":\"chat.completion.chunk\",\"created\":1792490608,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gxPziMM94gj\"}", + "data: {\"id\":\"chatcmpl-Eb0yms5JkEXzin8l8b8B8aSzAnUEw\",\"object\":\"chat.completion.chunk\",\"created\":1792490608,\"model\":\"gpt-5-nano-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\":\"gioYS2Q90o\"}", + "data: {\"id\":\"chatcmpl-Eb0yms5JkEXzin8l8b8B8aSzAnUEw\",\"object\":\"chat.completion.chunk\",\"created\":1792490608,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"xMTejKfYuPh\"}", + "data: {\"id\":\"chatcmpl-Eb0yms5JkEXzin8l8b8B8aSzAnUEw\",\"object\":\"chat.completion.chunk\",\"created\":1792490608,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"gxRhNfwvMcoluIf\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d7315c6eb9d0ba-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:03:32 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3995", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_db9afa3d3d8d4e6fbc277d0c3dbca747" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "9c18e34d76997d3c", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:03:35.723Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_VAz37DGPQjMeg7dwEPebWead", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_VAz37DGPQjMeg7dwEPebWead" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RvNDj\"}", + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9JB\"}", + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YMgN0\"}", + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Tx0l\"}", + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3\"}", + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dO8\"}", + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Wc8j3m\"}", + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xb2cd\"}", + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ptvgx\"}", + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7iPjXu\"}", + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"F\"}", + "data: {\"id\":\"chatcmpl-Eb0yqtEnX3fdPLsDdGt4uk6XIRJNb\",\"object\":\"chat.completion.chunk\",\"created\":1792490612,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"mPlcsKVbh2mFz0J\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73177fe40d0ba-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:03:35 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2935", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_c99e30f4c1fc46e9a7e99ca2fe560f22" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T09:52:39.683Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-latest-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-1-ai7-manual.cassette.json similarity index 88% rename from e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-latest-auto.cassette.json rename to e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-1-ai7-manual.cassette.json index 30afe71bd..78eab3c9c 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-latest-auto.cassette.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-1-ai7-manual.cassette.json @@ -4,7 +4,7 @@ "callIndex": 0, "id": "02bfffc5f7e45fcc", "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-07-20T14:52:25.812Z", + "recordedAt": "2026-10-20T10:03:16.373Z", "request": { "body": { "kind": "json", @@ -268,15 +268,15 @@ "response": { "body": { "chunks": [ - "data: {\"id\":\"chatcmpl-E3jduJXxphNYFI8ZkrTbQ6VKN5lff\",\"object\":\"chat.completion.chunk\",\"created\":1784559142,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_mhXleGKtQKxBEaZl2TwAWENj\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4TXwvdIx9VfYx\"}", - "data: {\"id\":\"chatcmpl-E3jduJXxphNYFI8ZkrTbQ6VKN5lff\",\"object\":\"chat.completion.chunk\",\"created\":1784559142,\"model\":\"gpt-5-nano-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\":\"qlHiC2THID\"}", - "data: {\"id\":\"chatcmpl-E3jduJXxphNYFI8ZkrTbQ6VKN5lff\",\"object\":\"chat.completion.chunk\",\"created\":1784559142,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5M5GoS9lm\"}", - "data: {\"id\":\"chatcmpl-E3jduJXxphNYFI8ZkrTbQ6VKN5lff\",\"object\":\"chat.completion.chunk\",\"created\":1784559142,\"model\":\"gpt-5-nano-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\":\"2xJ4ndtW\"}", - "data: {\"id\":\"chatcmpl-E3jduJXxphNYFI8ZkrTbQ6VKN5lff\",\"object\":\"chat.completion.chunk\",\"created\":1784559142,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rDH9woasL\"}", - "data: {\"id\":\"chatcmpl-E3jduJXxphNYFI8ZkrTbQ6VKN5lff\",\"object\":\"chat.completion.chunk\",\"created\":1784559142,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"AC8ALlnw4HI\"}", - "data: {\"id\":\"chatcmpl-E3jduJXxphNYFI8ZkrTbQ6VKN5lff\",\"object\":\"chat.completion.chunk\",\"created\":1784559142,\"model\":\"gpt-5-nano-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\":\"8CAXmNORTN\"}", - "data: {\"id\":\"chatcmpl-E3jduJXxphNYFI8ZkrTbQ6VKN5lff\",\"object\":\"chat.completion.chunk\",\"created\":1784559142,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"P7HS088Q2UB\"}", - "data: {\"id\":\"chatcmpl-E3jduJXxphNYFI8ZkrTbQ6VKN5lff\",\"object\":\"chat.completion.chunk\",\"created\":1784559142,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"ceow5M8GXDtGmr9\"}", + "data: {\"id\":\"chatcmpl-Eb0yWKiKoaQhRJjMqdZOtn0ugIXcO\",\"object\":\"chat.completion.chunk\",\"created\":1792490592,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_oTQSzHDyUi8wIVIWvBj08EH2\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"L0qf0szpCw68Y\"}", + "data: {\"id\":\"chatcmpl-Eb0yWKiKoaQhRJjMqdZOtn0ugIXcO\",\"object\":\"chat.completion.chunk\",\"created\":1792490592,\"model\":\"gpt-5-nano-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\":\"ErT6gWiV4m\"}", + "data: {\"id\":\"chatcmpl-Eb0yWKiKoaQhRJjMqdZOtn0ugIXcO\",\"object\":\"chat.completion.chunk\",\"created\":1792490592,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"UEKyvK7xb\"}", + "data: {\"id\":\"chatcmpl-Eb0yWKiKoaQhRJjMqdZOtn0ugIXcO\",\"object\":\"chat.completion.chunk\",\"created\":1792490592,\"model\":\"gpt-5-nano-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\":\"3Mh9I8jE\"}", + "data: {\"id\":\"chatcmpl-Eb0yWKiKoaQhRJjMqdZOtn0ugIXcO\",\"object\":\"chat.completion.chunk\",\"created\":1792490592,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"H3U8QD8bk\"}", + "data: {\"id\":\"chatcmpl-Eb0yWKiKoaQhRJjMqdZOtn0ugIXcO\",\"object\":\"chat.completion.chunk\",\"created\":1792490592,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TJjm0VndoxC\"}", + "data: {\"id\":\"chatcmpl-Eb0yWKiKoaQhRJjMqdZOtn0ugIXcO\",\"object\":\"chat.completion.chunk\",\"created\":1792490592,\"model\":\"gpt-5-nano-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\":\"NNzvA4tn3P\"}", + "data: {\"id\":\"chatcmpl-Eb0yWKiKoaQhRJjMqdZOtn0ugIXcO\",\"object\":\"chat.completion.chunk\",\"created\":1792490592,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"j2iwZB0ypsp\"}", + "data: {\"id\":\"chatcmpl-Eb0yWKiKoaQhRJjMqdZOtn0ugIXcO\",\"object\":\"chat.completion.chunk\",\"created\":1792490592,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"e2RRATFsmSHzb4l\"}", "data: [DONE]" ], "kind": "sse" @@ -285,18 +285,16 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "a1e2ca0d1abec946-IAD", - "connection": "keep-alive", + "cf-ray": "a4d730f85f9402aa-CDG", "content-type": "text/event-stream; charset=utf-8", - "date": "Mon, 20 Jul 2026 14:52:25 GMT", + "date": "Tue, 20 Oct 2026 10:03:16 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "3758", + "openai-processing-ms": "3978", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "transfer-encoding": "chunked", "x-content-type-options": "nosniff", "x-openai-proxy-wasm": "v0.1", "x-ratelimit-limit-requests": "30000", @@ -305,17 +303,16 @@ "x-ratelimit-remaining-tokens": "179999805", "x-ratelimit-reset-requests": "2ms", "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_2c7552a5eac94a7586babe88829e6a64" + "x-request-id": "req_ee6752cf1653405e99a506a9a99db670" }, - "status": 200, - "statusText": "OK" + "status": 200 } }, { "callIndex": 1, - "id": "9076672dec69b810", + "id": "607d2e3f9fac48e0", "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-07-20T14:52:27.896Z", + "recordedAt": "2026-10-20T10:03:19.793Z", "request": { "body": { "kind": "json", @@ -338,7 +335,7 @@ "arguments": "{\"city\":\"Vienna\"}", "name": "lookup_weather" }, - "id": "call_mhXleGKtQKxBEaZl2TwAWENj", + "id": "call_oTQSzHDyUi8wIVIWvBj08EH2", "type": "function" } ] @@ -346,7 +343,7 @@ { "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", "role": "tool", - "tool_call_id": "call_mhXleGKtQKxBEaZl2TwAWENj" + "tool_call_id": "call_oTQSzHDyUi8wIVIWvBj08EH2" } ], "model": "gpt-5-nano", @@ -598,18 +595,18 @@ "response": { "body": { "chunks": [ - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Iuoer\"}", - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Omd\"}", - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Bz1Y0\"}", - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"BWed\"}", - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"D\"}", - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0FB\"}", - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"D2rUzB\"}", - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PtMcu\"}", - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KF6c5\"}", - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"l3Afxb\"}", - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"3\"}", - "data: {\"id\":\"chatcmpl-E3jdys08eYN4lL67RNwOnxhC55ciz\",\"object\":\"chat.completion.chunk\",\"created\":1784559146,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"B6kJ0BZeZqChWQT\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fBhPb\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kHR\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sF1z5\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"s8oP\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"t\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"qJ0\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"q8XPxA\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KhVb1\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"QrZVd\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jGn00X\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"Z\"}", + "data: {\"id\":\"chatcmpl-Eb0yajpabCgTA1vDusNnERfQF1xkp\",\"object\":\"chat.completion.chunk\",\"created\":1792490596,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"Wvm1cbY6XczM6Wb\"}", "data: [DONE]" ], "kind": "sse" @@ -618,34 +615,31 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "a1e2ca25aa20c946-IAD", - "connection": "keep-alive", + "cf-ray": "a4d73113982502aa-CDG", "content-type": "text/event-stream; charset=utf-8", - "date": "Mon, 20 Jul 2026 14:52:27 GMT", + "date": "Tue, 20 Oct 2026 10:03:19 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "1894", + "openai-processing-ms": "3042", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "transfer-encoding": "chunked", "x-content-type-options": "nosniff", "x-openai-proxy-wasm": "v0.1", "x-ratelimit-limit-requests": "30000", "x-ratelimit-limit-tokens": "180000000", "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-remaining-tokens": "179999787", "x-ratelimit-reset-requests": "2ms", "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_585765b7523241a38133f2b76492d7ad" + "x-request-id": "req_c1abec6257c74748af01467f9b103444" }, - "status": 200, - "statusText": "OK" + "status": 200 } } ], "meta": { - "createdAt": "2026-07-20T14:52:28.130Z" + "createdAt": "2026-10-20T10:03:20.152Z" } } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-ai7-auto.cassette.json new file mode 100644 index 000000000..c4a4189f0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:02:33.324Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0xqS8UT40X0s7mfJ1VhVjFhPlqR\",\"object\":\"chat.completion.chunk\",\"created\":1792490550,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_sCXnx2RxhZfwQhyQakoLTBtQ\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OBlJsYzueva6Q\"}", + "data: {\"id\":\"chatcmpl-Eb0xqS8UT40X0s7mfJ1VhVjFhPlqR\",\"object\":\"chat.completion.chunk\",\"created\":1792490550,\"model\":\"gpt-5-nano-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\":\"POfuqxuCsw\"}", + "data: {\"id\":\"chatcmpl-Eb0xqS8UT40X0s7mfJ1VhVjFhPlqR\",\"object\":\"chat.completion.chunk\",\"created\":1792490550,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bpOCsA4dT\"}", + "data: {\"id\":\"chatcmpl-Eb0xqS8UT40X0s7mfJ1VhVjFhPlqR\",\"object\":\"chat.completion.chunk\",\"created\":1792490550,\"model\":\"gpt-5-nano-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\":\"PcMzsh0E\"}", + "data: {\"id\":\"chatcmpl-Eb0xqS8UT40X0s7mfJ1VhVjFhPlqR\",\"object\":\"chat.completion.chunk\",\"created\":1792490550,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"N0gJQ3vKh\"}", + "data: {\"id\":\"chatcmpl-Eb0xqS8UT40X0s7mfJ1VhVjFhPlqR\",\"object\":\"chat.completion.chunk\",\"created\":1792490550,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wBS8bdGccRl\"}", + "data: {\"id\":\"chatcmpl-Eb0xqS8UT40X0s7mfJ1VhVjFhPlqR\",\"object\":\"chat.completion.chunk\",\"created\":1792490550,\"model\":\"gpt-5-nano-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\":\"FUGryyLmw1\"}", + "data: {\"id\":\"chatcmpl-Eb0xqS8UT40X0s7mfJ1VhVjFhPlqR\",\"object\":\"chat.completion.chunk\",\"created\":1792490550,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"wAHqFFCdghp\"}", + "data: {\"id\":\"chatcmpl-Eb0xqS8UT40X0s7mfJ1VhVjFhPlqR\",\"object\":\"chat.completion.chunk\",\"created\":1792490550,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":281,\"total_tokens\":1323,\"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\":\"WLihrLHkK1RGLuT\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72ff4cc30fe94-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:02:33 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2498", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_6fbfdc936ae8488d8d762121f6457a2e" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "9f8c7d0230a38446", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:02:35.488Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_sCXnx2RxhZfwQhyQakoLTBtQ", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_sCXnx2RxhZfwQhyQakoLTBtQ" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VkN5N\"}", + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eLJ\"}", + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"D2Qp8\"}", + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Q1PA\"}", + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8\"}", + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jnc\"}", + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sA6GG9\"}", + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ssoUG\"}", + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zrsou\"}", + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kmBk8L\"}", + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"7\"}", + "data: {\"id\":\"chatcmpl-Eb0xtpgkqJhdAmuHGTZ9mgAhZTrSu\",\"object\":\"chat.completion.chunk\",\"created\":1792490553,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"xUZBbAlvVPI4M9g\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d7300698cafe94-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:02:35 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "1740", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999787", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_ef7321b79ab240f7b00978b13b5bf9e9" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:02:35.687Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-ai7-manual.cassette.json new file mode 100644 index 000000000..e31480282 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:02:16.228Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0xZe5jrnZkE4UAmXkouzerSAPK6\",\"object\":\"chat.completion.chunk\",\"created\":1792490533,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_mziMEOJwsoLuyMa1wjuwcuZk\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LzIK8DNA1EUoS\"}", + "data: {\"id\":\"chatcmpl-Eb0xZe5jrnZkE4UAmXkouzerSAPK6\",\"object\":\"chat.completion.chunk\",\"created\":1792490533,\"model\":\"gpt-5-nano-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\":\"CS3a7IGjNT\"}", + "data: {\"id\":\"chatcmpl-Eb0xZe5jrnZkE4UAmXkouzerSAPK6\",\"object\":\"chat.completion.chunk\",\"created\":1792490533,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6xw0bXa0L\"}", + "data: {\"id\":\"chatcmpl-Eb0xZe5jrnZkE4UAmXkouzerSAPK6\",\"object\":\"chat.completion.chunk\",\"created\":1792490533,\"model\":\"gpt-5-nano-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\":\"uyz9mmRT\"}", + "data: {\"id\":\"chatcmpl-Eb0xZe5jrnZkE4UAmXkouzerSAPK6\",\"object\":\"chat.completion.chunk\",\"created\":1792490533,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"opS7RY7wr\"}", + "data: {\"id\":\"chatcmpl-Eb0xZe5jrnZkE4UAmXkouzerSAPK6\",\"object\":\"chat.completion.chunk\",\"created\":1792490533,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Xe6FYA7JK6q\"}", + "data: {\"id\":\"chatcmpl-Eb0xZe5jrnZkE4UAmXkouzerSAPK6\",\"object\":\"chat.completion.chunk\",\"created\":1792490533,\"model\":\"gpt-5-nano-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\":\"xow3M5Yf9R\"}", + "data: {\"id\":\"chatcmpl-Eb0xZe5jrnZkE4UAmXkouzerSAPK6\",\"object\":\"chat.completion.chunk\",\"created\":1792490533,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"kibSonsEIt2\"}", + "data: {\"id\":\"chatcmpl-Eb0xZe5jrnZkE4UAmXkouzerSAPK6\",\"object\":\"chat.completion.chunk\",\"created\":1792490533,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"VmnK0WH8MmcnwRx\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72f89ad6260df-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:02:16 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2597", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_a6ff085c7efb4287b64c9f35575dd32c" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "8984b2fbe31f3d7b", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:02:20.828Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_mziMEOJwsoLuyMa1wjuwcuZk", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_mziMEOJwsoLuyMa1wjuwcuZk" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OSxvC\"}", + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rhH\"}", + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mWfOD\"}", + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZZI3\"}", + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"L\"}", + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sBZ\"}", + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"IZ1yZW\"}", + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"SftFS\"}", + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rKbR4\"}", + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3FPjYK\"}", + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"m\"}", + "data: {\"id\":\"chatcmpl-Eb0xdUJ0M4mXSMI5qOVfBtjGzsNQb\",\"object\":\"chat.completion.chunk\",\"created\":1792490537,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":338,\"total_tokens\":1425,\"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\":\"3e0jT6A71bHCuNv\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d72fa1ca7d60df-CDG", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:02:20 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "3258", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_59d1a2db173a4c74bdcaaf24d33fde90" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:02:21.622Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-latest-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-latest-ai7-auto.cassette.json new file mode 100644 index 000000000..72ca37d1a --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-latest-ai7-auto.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:03:01.468Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0yIV8aeKwMXQc58m7j8GdqsAU4A\",\"object\":\"chat.completion.chunk\",\"created\":1792490578,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_CoTblqFtAHEng8NmNRyP6Ngd\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hR17rUR7oT6Of\"}", + "data: {\"id\":\"chatcmpl-Eb0yIV8aeKwMXQc58m7j8GdqsAU4A\",\"object\":\"chat.completion.chunk\",\"created\":1792490578,\"model\":\"gpt-5-nano-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\":\"jRH7bQuqol\"}", + "data: {\"id\":\"chatcmpl-Eb0yIV8aeKwMXQc58m7j8GdqsAU4A\",\"object\":\"chat.completion.chunk\",\"created\":1792490578,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9R9avsh1X\"}", + "data: {\"id\":\"chatcmpl-Eb0yIV8aeKwMXQc58m7j8GdqsAU4A\",\"object\":\"chat.completion.chunk\",\"created\":1792490578,\"model\":\"gpt-5-nano-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\":\"Rklq6uB5\"}", + "data: {\"id\":\"chatcmpl-Eb0yIV8aeKwMXQc58m7j8GdqsAU4A\",\"object\":\"chat.completion.chunk\",\"created\":1792490578,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"53pv8x6Z6\"}", + "data: {\"id\":\"chatcmpl-Eb0yIV8aeKwMXQc58m7j8GdqsAU4A\",\"object\":\"chat.completion.chunk\",\"created\":1792490578,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"o3Z6mszSXfL\"}", + "data: {\"id\":\"chatcmpl-Eb0yIV8aeKwMXQc58m7j8GdqsAU4A\",\"object\":\"chat.completion.chunk\",\"created\":1792490578,\"model\":\"gpt-5-nano-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\":\"xOWXs22Z22\"}", + "data: {\"id\":\"chatcmpl-Eb0yIV8aeKwMXQc58m7j8GdqsAU4A\",\"object\":\"chat.completion.chunk\",\"created\":1792490578,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"sgiTFM9L8zh\"}", + "data: {\"id\":\"chatcmpl-Eb0yIV8aeKwMXQc58m7j8GdqsAU4A\",\"object\":\"chat.completion.chunk\",\"created\":1792490578,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"kFjAHPQmRmh03Sh\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d730a469573921-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:03:01 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2557", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_b4f908cbf1cf44d682e43839736d1ce7" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "8243949531cb4bf0", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:03:04.288Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_CoTblqFtAHEng8NmNRyP6Ngd", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_CoTblqFtAHEng8NmNRyP6Ngd" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"K2MP5\"}", + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Phm\"}", + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3IlLJ\"}", + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nZ6c\"}", + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"R\"}", + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MIw\"}", + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3h2JMF\"}", + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7jASm\"}", + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jBmAV\"}", + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hwuOqD\"}", + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"X\"}", + "data: {\"id\":\"chatcmpl-Eb0yLdT5sLNDjHDQ89N0ZZZcmP7d1\",\"object\":\"chat.completion.chunk\",\"created\":1792490581,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"KrwN87t9h4UDbHr\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d730b679333921-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:03:04 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2413", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_4c56c7250efb415fa6978dde005dea8a" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:03:04.453Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-latest-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-latest-ai7-manual.cassette.json new file mode 100644 index 000000000..a13eeb2ef --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-20-latest-ai7-manual.cassette.json @@ -0,0 +1,645 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "02bfffc5f7e45fcc", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:02:46.964Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0y3PQjm2m6ZKDiLI8PDts4OcSMd\",\"object\":\"chat.completion.chunk\",\"created\":1792490563,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_3llZ7ZOBsMtbqb88KUOyoVNP\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WK6lSsnq659MZ\"}", + "data: {\"id\":\"chatcmpl-Eb0y3PQjm2m6ZKDiLI8PDts4OcSMd\",\"object\":\"chat.completion.chunk\",\"created\":1792490563,\"model\":\"gpt-5-nano-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\":\"xNXwoqivCV\"}", + "data: {\"id\":\"chatcmpl-Eb0y3PQjm2m6ZKDiLI8PDts4OcSMd\",\"object\":\"chat.completion.chunk\",\"created\":1792490563,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2lX7rjCpe\"}", + "data: {\"id\":\"chatcmpl-Eb0y3PQjm2m6ZKDiLI8PDts4OcSMd\",\"object\":\"chat.completion.chunk\",\"created\":1792490563,\"model\":\"gpt-5-nano-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\":\"CjEBmAKP\"}", + "data: {\"id\":\"chatcmpl-Eb0y3PQjm2m6ZKDiLI8PDts4OcSMd\",\"object\":\"chat.completion.chunk\",\"created\":1792490563,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hVKFzcFia\"}", + "data: {\"id\":\"chatcmpl-Eb0y3PQjm2m6ZKDiLI8PDts4OcSMd\",\"object\":\"chat.completion.chunk\",\"created\":1792490563,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"E87HKCBt2ci\"}", + "data: {\"id\":\"chatcmpl-Eb0y3PQjm2m6ZKDiLI8PDts4OcSMd\",\"object\":\"chat.completion.chunk\",\"created\":1792490563,\"model\":\"gpt-5-nano-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\":\"PymWVlhw98\"}", + "data: {\"id\":\"chatcmpl-Eb0y3PQjm2m6ZKDiLI8PDts4OcSMd\",\"object\":\"chat.completion.chunk\",\"created\":1792490563,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"z0605oBhZYu\"}", + "data: {\"id\":\"chatcmpl-Eb0y3PQjm2m6ZKDiLI8PDts4OcSMd\",\"object\":\"chat.completion.chunk\",\"created\":1792490563,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"DBNOt0gVDLceyon\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d73046dfe7a58c-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:02:46 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2994", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999805", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_ecf4cfbaa6554ec59d68f0098ecfdc0c" + }, + "status": 200 + } + }, + { + "callIndex": 1, + "id": "f6e33d8e188aa88f", + "matchKey": "POST api.openai.com/v1/chat/completions", + "recordedAt": "2026-10-20T10:02:49.799Z", + "request": { + "body": { + "kind": "json", + "value": { + "messages": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "developer" + }, + { + "content": "What is the weather in Vienna?", + "role": "user" + }, + { + "content": null, + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"city\":\"Vienna\"}", + "name": "lookup_weather" + }, + "id": "call_3llZ7ZOBsMtbqb88KUOyoVNP", + "type": "function" + } + ] + }, + { + "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", + "role": "tool", + "tool_call_id": "call_3llZ7ZOBsMtbqb88KUOyoVNP" + } + ], + "model": "gpt-5-nano", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "function": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "name": "read", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "name": "write", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "name": "edit", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": ["path", "old_string", "new_string"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "name": "list", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "name": "find", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "name": "grep", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": ["query"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "name": "delete", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": ["path"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "name": "bash", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": ["script"], + "type": "object" + } + }, + "type": "function" + }, + { + "function": { + "description": "Get deterministic weather for a city.", + "name": "lookup_weather", + "parameters": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": ["city"], + "type": "object" + } + }, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions" + }, + "response": { + "body": { + "chunks": [ + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2RKYL\"}", + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eI3\"}", + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1VPdq\"}", + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mydt\"}", + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7\"}", + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9av\"}", + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vgF0cO\"}", + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zxfPw\"}", + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8u8zn\"}", + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hrF299\"}", + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"4\"}", + "data: {\"id\":\"chatcmpl-Eb0y7wWGAh4JZwDWnBxxzIz3IeGiO\",\"object\":\"chat.completion.chunk\",\"created\":1792490567,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"89fen0ztLdTzHpU\"}", + "data: [DONE]" + ], + "kind": "sse" + }, + "headers": { + "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", + "alt-svc": "h3=\":443\"; ma=86400", + "cf-cache-status": "DYNAMIC", + "cf-ray": "a4d7305bcde0a58c-AMS", + "content-type": "text/event-stream; charset=utf-8", + "date": "Tue, 20 Oct 2026 10:02:49 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "2458", + "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", + "openai-version": "2020-10-01", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "x-content-type-options": "nosniff", + "x-openai-proxy-wasm": "v0.1", + "x-ratelimit-limit-requests": "30000", + "x-ratelimit-limit-tokens": "180000000", + "x-ratelimit-remaining-requests": "29999", + "x-ratelimit-remaining-tokens": "179999790", + "x-ratelimit-reset-requests": "2ms", + "x-ratelimit-reset-tokens": "0s", + "x-request-id": "req_09306f0133d045aa818134604514140a" + }, + "status": 200 + } + } + ], + "meta": { + "createdAt": "2026-10-20T10:02:50.183Z" + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-auto.span-tree.json new file mode 100644 index 000000000..1f7f0f11b --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.13.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-auto.span-tree.txt new file mode 100644 index 000000000..2bff6f095 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.13.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-manual.span-tree.json new file mode 100644 index 000000000..15bf7a99e --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-manual.span-tree.txt new file mode 100644 index 000000000..0f9f56bc8 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-auto.span-tree.json new file mode 100644 index 000000000..a9c3369b1 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 192, + "text": 24, + "total": 216 + }, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 320, + "text": 18, + "total": 338 + }, + "raw": { + "completion_tokens": 338, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1425 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 338, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1425 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.13.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 512, + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2683 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-auto.span-tree.txt new file mode 100644 index 000000000..9d01a5d71 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.13.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 512, + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2683 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 192, + │ "text": 24, + │ "total": 216 + │ }, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 192, + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 192, + │ "time_to_first_token": 0, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 320, + "text": 18, + "total": 338 + }, + "raw": { + "completion_tokens": 338, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1425 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 320, + "completion_tokens": 338, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1425 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-manual.span-tree.json new file mode 100644 index 000000000..72219008f --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 192, + "text": 24, + "total": 216 + }, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 2491 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-manual.span-tree.txt new file mode 100644 index 000000000..6b292f056 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-13-latest-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 320, + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 2491 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 192, + │ "text": 24, + │ "total": 216 + │ }, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 192, + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 192, + │ "time_to_first_token": 0, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.json new file mode 100644 index 000000000..cd8111afb --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.14.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 448, + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 448, + "time_to_first_token": 0, + "tokens": 2619 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.txt new file mode 100644 index 000000000..5f3e28dea --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.14.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 448, + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 448, + "time_to_first_token": 0, + "tokens": 2619 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.json new file mode 100644 index 000000000..dda00f7fd --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 384, + "text": 24, + "total": 408 + }, + "raw": { + "completion_tokens": 408, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 384, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1450 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 384, + "completion_tokens": 408, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 1450 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 512, + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2683 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.txt new file mode 100644 index 000000000..51b69e3c8 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 512, + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2683 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 384, + │ "text": 24, + │ "total": 408 + │ }, + │ "raw": { + │ "completion_tokens": 408, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 384, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1450 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 384, + │ "completion_tokens": 408, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 384, + │ "time_to_first_token": 0, + │ "tokens": 1450 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.json new file mode 100644 index 000000000..22f05d9d2 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 0, + "text": 12, + "total": 12 + }, + "raw": { + "completion_tokens": 12, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1099 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 0, + "completion_tokens": 12, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 0, + "time_to_first_token": 0, + "tokens": 1099 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.14.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 292, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 2421 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.txt new file mode 100644 index 000000000..e2d808d33 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.14.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 256, + "completion_tokens": 292, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 2421 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 0, + "text": 12, + "total": 12 + }, + "raw": { + "completion_tokens": 12, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1099 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 0, + "completion_tokens": 12, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 0, + "time_to_first_token": 0, + "tokens": 1099 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.json new file mode 100644 index 000000000..553204794 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 192, + "text": 24, + "total": 216 + }, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 0, + "text": 12, + "total": 12 + }, + "raw": { + "completion_tokens": 12, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1099 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 0, + "completion_tokens": 12, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 0, + "time_to_first_token": 0, + "tokens": 1099 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 228, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 2357 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.txt new file mode 100644 index 000000000..bd1f22f13 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 228, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 2357 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 192, + │ "text": 24, + │ "total": 216 + │ }, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 192, + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 192, + │ "time_to_first_token": 0, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 0, + "text": 12, + "total": 12 + }, + "raw": { + "completion_tokens": 12, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1099 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 0, + "completion_tokens": 12, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 0, + "time_to_first_token": 0, + "tokens": 1099 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.json new file mode 100644 index 000000000..bd9094769 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 448, + "text": 24, + "total": 472 + }, + "raw": { + "completion_tokens": 472, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 448, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1514 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 448, + "completion_tokens": 472, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 448, + "time_to_first_token": 0, + "tokens": 1514 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 64, + "text": 18, + "total": 82 + }, + "raw": { + "completion_tokens": 82, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 64, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1169 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 64, + "completion_tokens": 82, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 64, + "time_to_first_token": 0, + "tokens": 1169 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.15.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 512, + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2683 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.txt new file mode 100644 index 000000000..e0622a581 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.15.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 512, + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2683 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 448, + │ "text": 24, + │ "total": 472 + │ }, + │ "raw": { + │ "completion_tokens": 472, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 448, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1514 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 448, + │ "completion_tokens": 472, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 448, + │ "time_to_first_token": 0, + │ "tokens": 1514 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 64, + "text": 18, + "total": 82 + }, + "raw": { + "completion_tokens": 82, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 64, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1169 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 64, + "completion_tokens": 82, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 64, + "time_to_first_token": 0, + "tokens": 1169 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.json new file mode 100644 index 000000000..15bf7a99e --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.txt new file mode 100644 index 000000000..0f9f56bc8 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.json similarity index 82% rename from e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-manual.span-tree.json rename to e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.json index a6a04fcff..9f9222615 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-manual.span-tree.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.json @@ -9,13 +9,8 @@ "type": "llm", "children": [], "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -26,8 +21,9 @@ "role": "user" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -266,53 +262,67 @@ ] }, "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ + "content": [ { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", + "input": { + "city": "Vienna" + }, + "toolCallId": "", "toolName": "lookup_weather", "type": "tool-call" } ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 }, - "outputTokens": { - "reasoning": 384, - "text": 24, - "total": 408 + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 256, + "textTokens": 24 }, + "outputTokens": 280, "raw": { - "completion_tokens": 408, + "completion_tokens": 280, "completion_tokens_details": { "accepted_prediction_tokens": 0, - "reasoning_tokens": 384, + "reasoning_tokens": 256, "rejected_prediction_tokens": 0 }, "prompt_tokens": 1042, "prompt_tokens_details": { "cached_tokens": 0 }, - "total_tokens": 1450 - } + "total_tokens": 1322 + }, + "totalTokens": 1322 } }, "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { - "completion_tokens": 408, + "completion_tokens": 280, + "prompt_cached_tokens": 0, "prompt_tokens": 1042, - "tokens": 1450 + "tokens": 1322 } }, { @@ -326,6 +336,14 @@ "city": "Vienna", "condition": "sunny", "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" } }, { @@ -333,13 +351,8 @@ "type": "llm", "children": [], "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -381,8 +394,9 @@ "role": "tool" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -621,23 +635,33 @@ ] }, "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 192, + "textTokens": 18 }, + "outputTokens": 210, "raw": { "completion_tokens": 210, "completion_tokens_details": { @@ -650,21 +674,32 @@ "cached_tokens": 0 }, "total_tokens": 1297 - } + }, + "totalTokens": 1297 } }, "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { "completion_tokens": 210, + "prompt_cached_tokens": 0, "prompt_tokens": 1087, "tokens": 1297 } } ], "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, { "content": [ { @@ -684,13 +719,17 @@ "integration_name": "cloudflare-think", "sdk_language": "typescript" }, + "cloudflare_think.version": "0.15.0", + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { - "completion_tokens": 618, + "completion_tokens": 490, + "prompt_cached_tokens": 0, "prompt_tokens": 2129, - "tokens": 2747 + "time_to_first_token": 0, + "tokens": 2619 } } ] diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.txt new file mode 100644 index 000000000..04d4a7d48 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.txt @@ -0,0 +1,716 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.15.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2619 + } + ├── doStream [llm] + │ input: { + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "content": [ + │ { + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, + │ "usage": { + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 + │ }, + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 256, + │ "textTokens": 24 + │ }, + │ "outputTokens": 280, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ }, + │ "totalTokens": 1322 + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } + └── doStream [llm] + input: { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 192, + "textTokens": 18 + }, + "outputTokens": 210, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + }, + "totalTokens": 1297 + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.json new file mode 100644 index 000000000..d696ec9a5 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 320, + "text": 24, + "total": 344 + }, + "raw": { + "completion_tokens": 344, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1386 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 344, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1386 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 0, + "text": 12, + "total": 12 + }, + "raw": { + "completion_tokens": 12, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1099 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 0, + "completion_tokens": 12, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 0, + "time_to_first_token": 0, + "tokens": 1099 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 356, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2485 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.txt new file mode 100644 index 000000000..c2864efa8 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 356, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2485 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 320, + │ "text": 24, + │ "total": 344 + │ }, + │ "raw": { + │ "completion_tokens": 344, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 320, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1386 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 320, + │ "completion_tokens": 344, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 320, + │ "time_to_first_token": 0, + │ "tokens": 1386 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 0, + "text": 12, + "total": 12 + }, + "raw": { + "completion_tokens": 12, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1099 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 0, + "completion_tokens": 12, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 0, + "time_to_first_token": 0, + "tokens": 1099 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.json new file mode 100644 index 000000000..e1a1f66c0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 384, + "text": 24, + "total": 408 + }, + "raw": { + "completion_tokens": 408, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 384, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1450 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 384, + "completion_tokens": 408, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 1450 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.15.1", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 512, + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2683 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.txt new file mode 100644 index 000000000..0cb046e1c --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.15.1", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 512, + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2683 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 384, + │ "text": 24, + │ "total": 408 + │ }, + │ "raw": { + │ "completion_tokens": 408, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 384, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1450 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 384, + │ "completion_tokens": 408, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 384, + │ "time_to_first_token": 0, + │ "tokens": 1450 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.json new file mode 100644 index 000000000..d113870e7 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 192, + "text": 24, + "total": 216 + }, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.txt new file mode 100644 index 000000000..93e394db2 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 192, + │ "text": 24, + │ "total": 216 + │ }, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 192, + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 192, + │ "time_to_first_token": 0, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.json similarity index 82% rename from e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-auto.span-tree.json rename to e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.json index a3c1ef4f0..7e9196010 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-auto.span-tree.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.json @@ -9,13 +9,8 @@ "type": "llm", "children": [], "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -26,8 +21,9 @@ "role": "user" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -266,53 +262,67 @@ ] }, "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ + "content": [ { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", + "input": { + "city": "Vienna" + }, + "toolCallId": "", "toolName": "lookup_weather", "type": "tool-call" } ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 }, - "outputTokens": { - "reasoning": 128, - "text": 24, - "total": 152 + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 256, + "textTokens": 24 }, + "outputTokens": 280, "raw": { - "completion_tokens": 152, + "completion_tokens": 280, "completion_tokens_details": { "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, + "reasoning_tokens": 256, "rejected_prediction_tokens": 0 }, "prompt_tokens": 1042, "prompt_tokens_details": { "cached_tokens": 0 }, - "total_tokens": 1194 - } + "total_tokens": 1322 + }, + "totalTokens": 1322 } }, "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { - "completion_tokens": 152, + "completion_tokens": 280, + "prompt_cached_tokens": 0, "prompt_tokens": 1042, - "tokens": 1194 + "tokens": 1322 } }, { @@ -326,6 +336,14 @@ "city": "Vienna", "condition": "sunny", "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" } }, { @@ -333,13 +351,8 @@ "type": "llm", "children": [], "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -381,8 +394,9 @@ "role": "tool" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -621,25 +635,35 @@ ] }, "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 }, - "outputTokens": { - "reasoning": 128, - "text": 19, - "total": 147 + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 }, + "outputTokens": 146, "raw": { - "completion_tokens": 147, + "completion_tokens": 146, "completion_tokens_details": { "accepted_prediction_tokens": 0, "reasoning_tokens": 128, @@ -649,22 +673,33 @@ "prompt_tokens_details": { "cached_tokens": 0 }, - "total_tokens": 1234 - } + "total_tokens": 1233 + }, + "totalTokens": 1233 } }, "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { - "completion_tokens": 147, + "completion_tokens": 146, + "prompt_cached_tokens": 0, "prompt_tokens": 1087, - "tokens": 1234 + "tokens": 1233 } } ], "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, { "content": [ { @@ -684,13 +719,17 @@ "integration_name": "cloudflare-think", "sdk_language": "typescript" }, + "cloudflare_think.version": "0.15.1", + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { - "completion_tokens": 299, + "completion_tokens": 426, + "prompt_cached_tokens": 0, "prompt_tokens": 2129, - "tokens": 2428 + "time_to_first_token": 0, + "tokens": 2555 } } ] diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.txt similarity index 81% rename from e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-auto.span-tree.txt rename to e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.txt index c9efdefd6..66b2d2572 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-auto.span-tree.txt +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.txt @@ -1,6 +1,10 @@ span_tree: └── Think.runTurn [task] input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, { "content": [ { @@ -20,23 +24,22 @@ span_tree: "integration_name": "cloudflare-think", "sdk_language": "typescript" }, + "cloudflare_think.version": "0.15.1", + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" } metrics: { - "completion_tokens": 299, + "completion_tokens": 426, + "prompt_cached_tokens": 0, "prompt_tokens": 2129, - "tokens": 2428 + "time_to_first_token": 0, + "tokens": 2555 } ├── doStream [llm] │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ │ { │ "content": [ │ { @@ -47,8 +50,9 @@ span_tree: │ "role": "user" │ } │ ], - │ "toolChoice": { - │ "type": "auto" + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" │ }, │ "tools": [ │ { @@ -287,53 +291,67 @@ span_tree: │ ] │ } │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ + │ "content": [ │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", │ "toolName": "lookup_weather", │ "type": "tool-call" │ } │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 │ }, - │ "outputTokens": { - │ "reasoning": 128, - │ "text": 24, - │ "total": 152 + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 256, + │ "textTokens": 24 │ }, + │ "outputTokens": 280, │ "raw": { - │ "completion_tokens": 152, + │ "completion_tokens": 280, │ "completion_tokens_details": { │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 128, + │ "reasoning_tokens": 256, │ "rejected_prediction_tokens": 0 │ }, │ "prompt_tokens": 1042, │ "prompt_tokens_details": { │ "cached_tokens": 0 │ }, - │ "total_tokens": 1194 - │ } + │ "total_tokens": 1322 + │ }, + │ "totalTokens": 1322 │ } │ } │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", │ "model": "gpt-5-nano", │ "provider": "openai.chat" │ } │ metrics: { - │ "completion_tokens": 152, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, │ "prompt_tokens": 1042, - │ "tokens": 1194 + │ "tokens": 1322 │ } ├── lookup_weather [tool] │ input: { @@ -344,15 +362,18 @@ span_tree: │ "condition": "sunny", │ "degreesC": 21 │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } └── doStream [llm] input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -394,8 +415,9 @@ span_tree: "role": "tool" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -634,25 +656,35 @@ span_tree: ] } output: { - "finishReason": { - "raw": "stop", - "unified": "stop" + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 }, - "outputTokens": { - "reasoning": 128, - "text": 19, - "total": 147 + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 }, + "outputTokens": 146, "raw": { - "completion_tokens": 147, + "completion_tokens": 146, "completion_tokens_details": { "accepted_prediction_tokens": 0, "reasoning_tokens": 128, @@ -662,16 +694,23 @@ span_tree: "prompt_tokens_details": { "cached_tokens": 0 }, - "total_tokens": 1234 - } + "total_tokens": 1233 + }, + "totalTokens": 1233 } } metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" } metrics: { - "completion_tokens": 147, + "completion_tokens": 146, + "prompt_cached_tokens": 0, "prompt_tokens": 1087, - "tokens": 1234 + "tokens": 1233 } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.json new file mode 100644 index 000000000..c6d838c7c --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 512, + "text": 24, + "total": 536 + }, + "raw": { + "completion_tokens": 536, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 512, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1578 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 512, + "completion_tokens": 536, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 1578 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 746, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2875 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.txt new file mode 100644 index 000000000..f4ee26a54 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 746, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2875 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 512, + │ "text": 24, + │ "total": 536 + │ }, + │ "raw": { + │ "completion_tokens": 536, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 512, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1578 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 512, + │ "completion_tokens": 536, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 512, + │ "time_to_first_token": 0, + │ "tokens": 1578 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.json new file mode 100644 index 000000000..002ec074e --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 18, + "total": 274 + }, + "raw": { + "completion_tokens": 274, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1361 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 274, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1361 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.16.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 512, + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2683 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.txt new file mode 100644 index 000000000..38f12dc23 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.16.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 512, + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2683 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 18, + "total": 274 + }, + "raw": { + "completion_tokens": 274, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1361 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 256, + "completion_tokens": 274, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1361 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.json new file mode 100644 index 000000000..19098c709 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 576, + "text": 24, + "total": 600 + }, + "raw": { + "completion_tokens": 600, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 576, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1642 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 576, + "completion_tokens": 600, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 576, + "time_to_first_token": 0, + "tokens": 1642 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 768, + "completion_tokens": 810, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 768, + "time_to_first_token": 0, + "tokens": 2939 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.txt new file mode 100644 index 000000000..89fd3bfa2 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 768, + "completion_tokens": 810, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 768, + "time_to_first_token": 0, + "tokens": 2939 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 576, + │ "text": 24, + │ "total": 600 + │ }, + │ "raw": { + │ "completion_tokens": 600, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 576, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1642 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 576, + │ "completion_tokens": 600, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 576, + │ "time_to_first_token": 0, + │ "tokens": 1642 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.json similarity index 82% rename from e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-manual.span-tree.json rename to e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.json index 91d62d024..2013e1597 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-manual.span-tree.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.json @@ -9,13 +9,8 @@ "type": "llm", "children": [], "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -26,8 +21,9 @@ "role": "user" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -266,53 +262,67 @@ ] }, "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ + "content": [ { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", + "input": { + "city": "Vienna" + }, + "toolCallId": "", "toolName": "lookup_weather", "type": "tool-call" } ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 }, - "outputTokens": { - "reasoning": 448, - "text": 24, - "total": 472 + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 256, + "textTokens": 24 }, + "outputTokens": 280, "raw": { - "completion_tokens": 472, + "completion_tokens": 280, "completion_tokens_details": { "accepted_prediction_tokens": 0, - "reasoning_tokens": 448, + "reasoning_tokens": 256, "rejected_prediction_tokens": 0 }, "prompt_tokens": 1042, "prompt_tokens_details": { "cached_tokens": 0 }, - "total_tokens": 1514 - } + "total_tokens": 1322 + }, + "totalTokens": 1322 } }, "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { - "completion_tokens": 472, + "completion_tokens": 280, + "prompt_cached_tokens": 0, "prompt_tokens": 1042, - "tokens": 1514 + "tokens": 1322 } }, { @@ -326,6 +336,14 @@ "city": "Vienna", "condition": "sunny", "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" } }, { @@ -333,13 +351,8 @@ "type": "llm", "children": [], "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -381,8 +394,9 @@ "role": "tool" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -621,23 +635,33 @@ ] }, "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 }, - "outputTokens": { - "reasoning": 320, - "text": 18, - "total": 338 + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 320, + "textTokens": 18 }, + "outputTokens": 338, "raw": { "completion_tokens": 338, "completion_tokens_details": { @@ -650,21 +674,32 @@ "cached_tokens": 0 }, "total_tokens": 1425 - } + }, + "totalTokens": 1425 } }, "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { "completion_tokens": 338, + "prompt_cached_tokens": 0, "prompt_tokens": 1087, "tokens": 1425 } } ], "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, { "content": [ { @@ -684,13 +719,17 @@ "integration_name": "cloudflare-think", "sdk_language": "typescript" }, + "cloudflare_think.version": "0.16.0", + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { - "completion_tokens": 810, + "completion_tokens": 618, + "prompt_cached_tokens": 0, "prompt_tokens": 2129, - "tokens": 2939 + "time_to_first_token": 0, + "tokens": 2747 } } ] diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.txt similarity index 82% rename from e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-manual.span-tree.txt rename to e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.txt index 97bbc4b51..8282bcccb 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-manual.span-tree.txt +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.txt @@ -1,6 +1,10 @@ span_tree: └── Think.runTurn [task] input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, { "content": [ { @@ -20,23 +24,22 @@ span_tree: "integration_name": "cloudflare-think", "sdk_language": "typescript" }, + "cloudflare_think.version": "0.16.0", + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" } metrics: { - "completion_tokens": 810, + "completion_tokens": 618, + "prompt_cached_tokens": 0, "prompt_tokens": 2129, - "tokens": 2939 + "time_to_first_token": 0, + "tokens": 2747 } ├── doStream [llm] │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ │ { │ "content": [ │ { @@ -47,8 +50,9 @@ span_tree: │ "role": "user" │ } │ ], - │ "toolChoice": { - │ "type": "auto" + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" │ }, │ "tools": [ │ { @@ -287,53 +291,67 @@ span_tree: │ ] │ } │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ + │ "content": [ │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", │ "toolName": "lookup_weather", │ "type": "tool-call" │ } │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 │ }, - │ "outputTokens": { - │ "reasoning": 448, - │ "text": 24, - │ "total": 472 + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 256, + │ "textTokens": 24 │ }, + │ "outputTokens": 280, │ "raw": { - │ "completion_tokens": 472, + │ "completion_tokens": 280, │ "completion_tokens_details": { │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 448, + │ "reasoning_tokens": 256, │ "rejected_prediction_tokens": 0 │ }, │ "prompt_tokens": 1042, │ "prompt_tokens_details": { │ "cached_tokens": 0 │ }, - │ "total_tokens": 1514 - │ } + │ "total_tokens": 1322 + │ }, + │ "totalTokens": 1322 │ } │ } │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", │ "model": "gpt-5-nano", │ "provider": "openai.chat" │ } │ metrics: { - │ "completion_tokens": 472, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, │ "prompt_tokens": 1042, - │ "tokens": 1514 + │ "tokens": 1322 │ } ├── lookup_weather [tool] │ input: { @@ -344,15 +362,18 @@ span_tree: │ "condition": "sunny", │ "degreesC": 21 │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } └── doStream [llm] input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -394,8 +415,9 @@ span_tree: "role": "tool" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -634,23 +656,33 @@ span_tree: ] } output: { - "finishReason": { - "raw": "stop", - "unified": "stop" + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 }, - "outputTokens": { - "reasoning": 320, - "text": 18, - "total": 338 + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 320, + "textTokens": 18 }, + "outputTokens": 338, "raw": { "completion_tokens": 338, "completion_tokens_details": { @@ -663,15 +695,22 @@ span_tree: "cached_tokens": 0 }, "total_tokens": 1425 - } + }, + "totalTokens": 1425 } } metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" } metrics: { "completion_tokens": 338, + "prompt_cached_tokens": 0, "prompt_tokens": 1087, "tokens": 1425 } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.json new file mode 100644 index 000000000..6cf811fa2 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 192, + "text": 24, + "total": 216 + }, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2555 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.txt new file mode 100644 index 000000000..1a020a594 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2555 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 192, + │ "text": 24, + │ "total": 216 + │ }, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 192, + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 192, + │ "time_to_first_token": 0, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.json new file mode 100644 index 000000000..11c0e5ce7 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 19, + "total": 275 + }, + "raw": { + "completion_tokens": 275, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1362 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 275, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1362 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.16.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 512, + "completion_tokens": 555, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2684 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.txt new file mode 100644 index 000000000..2161b4a8b --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.16.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 512, + "completion_tokens": 555, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 512, + "time_to_first_token": 0, + "tokens": 2684 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 19, + "total": 275 + }, + "raw": { + "completion_tokens": 275, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1362 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 256, + "completion_tokens": 275, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1362 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.json new file mode 100644 index 000000000..9768297eb --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 320, + "text": 24, + "total": 344 + }, + "raw": { + "completion_tokens": 344, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1386 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 344, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1386 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 18, + "total": 274 + }, + "raw": { + "completion_tokens": 274, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1361 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 274, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1361 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 576, + "completion_tokens": 618, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 576, + "time_to_first_token": 0, + "tokens": 2747 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.txt new file mode 100644 index 000000000..c281ee29c --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 576, + "completion_tokens": 618, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 576, + "time_to_first_token": 0, + "tokens": 2747 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 320, + │ "text": 24, + │ "total": 344 + │ }, + │ "raw": { + │ "completion_tokens": 344, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 320, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1386 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 320, + │ "completion_tokens": 344, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 320, + │ "time_to_first_token": 0, + │ "tokens": 1386 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 18, + "total": 274 + }, + "raw": { + "completion_tokens": 274, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1361 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 256, + "completion_tokens": 274, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1361 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.json new file mode 100644 index 000000000..45d55b9b7 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.json @@ -0,0 +1,736 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 + }, + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 256, + "textTokens": 24 + }, + "outputTokens": 280, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + }, + "totalTokens": 1322 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.16.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2555 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.txt new file mode 100644 index 000000000..78b7aaf04 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.txt @@ -0,0 +1,716 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.16.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2555 + } + ├── doStream [llm] + │ input: { + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "content": [ + │ { + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, + │ "usage": { + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 + │ }, + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 256, + │ "textTokens": 24 + │ }, + │ "outputTokens": 280, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ }, + │ "totalTokens": 1322 + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } + └── doStream [llm] + input: { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.json new file mode 100644 index 000000000..6aa5672b0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 320, + "text": 24, + "total": 344 + }, + "raw": { + "completion_tokens": 344, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1386 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 344, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1386 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2683 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.txt new file mode 100644 index 000000000..39efb478b --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2683 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 320, + │ "text": 24, + │ "total": 344 + │ }, + │ "raw": { + │ "completion_tokens": 344, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 320, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1386 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 320, + │ "completion_tokens": 344, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 320, + │ "time_to_first_token": 0, + │ "tokens": 1386 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.json new file mode 100644 index 000000000..411bafadb --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 192, + "text": 24, + "total": 216 + }, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.17.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 2491 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.txt new file mode 100644 index 000000000..e8b6b5f21 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.17.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 320, + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 2491 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 192, + │ "text": 24, + │ "total": 216 + │ }, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 192, + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 192, + │ "time_to_first_token": 0, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.json new file mode 100644 index 000000000..99acecd24 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 448, + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 448, + "time_to_first_token": 0, + "tokens": 2619 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.txt new file mode 100644 index 000000000..5425b2d9f --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 448, + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 448, + "time_to_first_token": 0, + "tokens": 2619 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.json new file mode 100644 index 000000000..73db5c04c --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.json @@ -0,0 +1,736 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 + }, + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 384, + "textTokens": 24 + }, + "outputTokens": 408, + "raw": { + "completion_tokens": 408, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 384, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1450 + }, + "totalTokens": 1450 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 408, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "tokens": 1450 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 256, + "textTokens": 18 + }, + "outputTokens": 274, + "raw": { + "completion_tokens": 274, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1361 + }, + "totalTokens": 1361 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 274, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1361 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.17.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 682, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2811 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.txt similarity index 82% rename from e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-manual.span-tree.txt rename to e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.txt index 361930654..6c1c8d621 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-manual.span-tree.txt +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.txt @@ -1,6 +1,10 @@ span_tree: └── Think.runTurn [task] input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, { "content": [ { @@ -20,23 +24,22 @@ span_tree: "integration_name": "cloudflare-think", "sdk_language": "typescript" }, + "cloudflare_think.version": "0.17.0", + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" } metrics: { - "completion_tokens": 618, + "completion_tokens": 682, + "prompt_cached_tokens": 0, "prompt_tokens": 2129, - "tokens": 2747 + "time_to_first_token": 0, + "tokens": 2811 } ├── doStream [llm] │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ │ { │ "content": [ │ { @@ -47,8 +50,9 @@ span_tree: │ "role": "user" │ } │ ], - │ "toolChoice": { - │ "type": "auto" + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" │ }, │ "tools": [ │ { @@ -287,30 +291,37 @@ span_tree: │ ] │ } │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ + │ "content": [ │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", │ "toolName": "lookup_weather", │ "type": "tool-call" │ } │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 │ }, - │ "outputTokens": { - │ "reasoning": 384, - │ "text": 24, - │ "total": 408 + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 384, + │ "textTokens": 24 │ }, + │ "outputTokens": 408, │ "raw": { │ "completion_tokens": 408, │ "completion_tokens_details": { @@ -323,15 +334,22 @@ span_tree: │ "cached_tokens": 0 │ }, │ "total_tokens": 1450 - │ } + │ }, + │ "totalTokens": 1450 │ } │ } │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", │ "model": "gpt-5-nano", │ "provider": "openai.chat" │ } │ metrics: { │ "completion_tokens": 408, + │ "prompt_cached_tokens": 0, │ "prompt_tokens": 1042, │ "tokens": 1450 │ } @@ -344,15 +362,18 @@ span_tree: │ "condition": "sunny", │ "degreesC": 21 │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } └── doStream [llm] input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -394,8 +415,9 @@ span_tree: "role": "tool" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -634,44 +656,61 @@ span_tree: ] } output: { - "finishReason": { - "raw": "stop", - "unified": "stop" + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 256, + "textTokens": 18 }, + "outputTokens": 274, "raw": { - "completion_tokens": 210, + "completion_tokens": 274, "completion_tokens_details": { "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, + "reasoning_tokens": 256, "rejected_prediction_tokens": 0 }, "prompt_tokens": 1087, "prompt_tokens_details": { "cached_tokens": 0 }, - "total_tokens": 1297 - } + "total_tokens": 1361 + }, + "totalTokens": 1361 } } metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" } metrics: { - "completion_tokens": 210, + "completion_tokens": 274, + "prompt_cached_tokens": 0, "prompt_tokens": 1087, - "tokens": 1297 + "tokens": 1361 } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.json new file mode 100644 index 000000000..2cfa395c1 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2619 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.txt new file mode 100644 index 000000000..62de172a1 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2619 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.json new file mode 100644 index 000000000..684987372 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 0, + "text": 12, + "total": 12 + }, + "raw": { + "completion_tokens": 12, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1099 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 0, + "completion_tokens": 12, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 0, + "time_to_first_token": 0, + "tokens": 1099 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.17.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 292, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 2421 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.txt new file mode 100644 index 000000000..93226bdfd --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.17.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 256, + "completion_tokens": 292, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 2421 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 0, + "text": 12, + "total": 12 + }, + "raw": { + "completion_tokens": 12, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1099 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 0, + "completion_tokens": 12, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 0, + "time_to_first_token": 0, + "tokens": 1099 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.json new file mode 100644 index 000000000..72219008f --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 192, + "text": 24, + "total": 216 + }, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 2491 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.txt new file mode 100644 index 000000000..6b292f056 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 320, + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 2491 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 192, + │ "text": 24, + │ "total": 216 + │ }, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 192, + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 192, + │ "time_to_first_token": 0, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.json new file mode 100644 index 000000000..05487f627 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.json @@ -0,0 +1,736 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 + }, + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 320, + "textTokens": 24 + }, + "outputTokens": 344, + "raw": { + "completion_tokens": 344, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1386 + }, + "totalTokens": 1386 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 344, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "tokens": 1386 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.17.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2619 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.txt new file mode 100644 index 000000000..f844a4068 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.txt @@ -0,0 +1,716 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.17.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2619 + } + ├── doStream [llm] + │ input: { + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "content": [ + │ { + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, + │ "usage": { + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 + │ }, + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 320, + │ "textTokens": 24 + │ }, + │ "outputTokens": 344, + │ "raw": { + │ "completion_tokens": 344, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 320, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1386 + │ }, + │ "totalTokens": 1386 + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_tokens": 344, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "tokens": 1386 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } + └── doStream [llm] + input: { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.json new file mode 100644 index 000000000..2cfa395c1 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2619 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.txt new file mode 100644 index 000000000..62de172a1 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2619 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.json new file mode 100644 index 000000000..75b82834a --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 25, + "total": 281 + }, + "raw": { + "completion_tokens": 281, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1323 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 281, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1323 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 320, + "text": 18, + "total": 338 + }, + "raw": { + "completion_tokens": 338, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1425 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 338, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1425 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.18.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 576, + "completion_tokens": 619, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 576, + "time_to_first_token": 0, + "tokens": 2748 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.txt new file mode 100644 index 000000000..230ab3a14 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.18.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 576, + "completion_tokens": 619, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 576, + "time_to_first_token": 0, + "tokens": 2748 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 25, + │ "total": 281 + │ }, + │ "raw": { + │ "completion_tokens": 281, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1323 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 281, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1323 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 320, + "text": 18, + "total": 338 + }, + "raw": { + "completion_tokens": 338, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1425 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 320, + "completion_tokens": 338, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1425 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.json new file mode 100644 index 000000000..19417d885 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 384, + "text": 24, + "total": 408 + }, + "raw": { + "completion_tokens": 408, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 384, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1450 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 384, + "completion_tokens": 408, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 1450 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 18, + "total": 274 + }, + "raw": { + "completion_tokens": 274, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1361 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 274, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1361 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 640, + "completion_tokens": 682, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 640, + "time_to_first_token": 0, + "tokens": 2811 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.txt new file mode 100644 index 000000000..bb77d8e98 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 640, + "completion_tokens": 682, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 640, + "time_to_first_token": 0, + "tokens": 2811 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 384, + │ "text": 24, + │ "total": 408 + │ }, + │ "raw": { + │ "completion_tokens": 408, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 384, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1450 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 384, + │ "completion_tokens": 408, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 384, + │ "time_to_first_token": 0, + │ "tokens": 1450 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 18, + "total": 274 + }, + "raw": { + "completion_tokens": 274, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1361 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 256, + "completion_tokens": 274, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1361 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.json similarity index 83% rename from e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-auto.span-tree.json rename to e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.json index 7c4371c07..4b774d5a3 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-auto.span-tree.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.json @@ -9,13 +9,8 @@ "type": "llm", "children": [], "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -26,8 +21,9 @@ "role": "user" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -266,30 +262,37 @@ ] }, "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ + "content": [ { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", + "input": { + "city": "Vienna" + }, + "toolCallId": "", "toolName": "lookup_weather", "type": "tool-call" } ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 }, - "outputTokens": { - "reasoning": 320, - "text": 24, - "total": 344 + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 320, + "textTokens": 24 }, + "outputTokens": 344, "raw": { "completion_tokens": 344, "completion_tokens_details": { @@ -302,15 +305,22 @@ "cached_tokens": 0 }, "total_tokens": 1386 - } + }, + "totalTokens": 1386 } }, "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { "completion_tokens": 344, + "prompt_cached_tokens": 0, "prompt_tokens": 1042, "tokens": 1386 } @@ -326,6 +336,14 @@ "city": "Vienna", "condition": "sunny", "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" } }, { @@ -333,13 +351,8 @@ "type": "llm", "children": [], "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -381,8 +394,9 @@ "role": "tool" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -621,23 +635,33 @@ ] }, "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 192, + "textTokens": 18 }, + "outputTokens": 210, "raw": { "completion_tokens": 210, "completion_tokens_details": { @@ -650,21 +674,32 @@ "cached_tokens": 0 }, "total_tokens": 1297 - } + }, + "totalTokens": 1297 } }, "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { "completion_tokens": 210, + "prompt_cached_tokens": 0, "prompt_tokens": 1087, "tokens": 1297 } } ], "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, { "content": [ { @@ -684,12 +719,16 @@ "integration_name": "cloudflare-think", "sdk_language": "typescript" }, + "cloudflare_think.version": "0.18.0", + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" }, "metrics": { "completion_tokens": 554, + "prompt_cached_tokens": 0, "prompt_tokens": 2129, + "time_to_first_token": 0, "tokens": 2683 } } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.txt similarity index 83% rename from e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-auto.span-tree.txt rename to e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.txt index e200fee39..9a02345fc 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-latest-auto.span-tree.txt +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.txt @@ -1,6 +1,10 @@ span_tree: └── Think.runTurn [task] input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, { "content": [ { @@ -20,23 +24,22 @@ span_tree: "integration_name": "cloudflare-think", "sdk_language": "typescript" }, + "cloudflare_think.version": "0.18.0", + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" } metrics: { "completion_tokens": 554, + "prompt_cached_tokens": 0, "prompt_tokens": 2129, + "time_to_first_token": 0, "tokens": 2683 } ├── doStream [llm] │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ │ { │ "content": [ │ { @@ -47,8 +50,9 @@ span_tree: │ "role": "user" │ } │ ], - │ "toolChoice": { - │ "type": "auto" + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" │ }, │ "tools": [ │ { @@ -287,30 +291,37 @@ span_tree: │ ] │ } │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ + │ "content": [ │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", │ "toolName": "lookup_weather", │ "type": "tool-call" │ } │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 │ }, - │ "outputTokens": { - │ "reasoning": 320, - │ "text": 24, - │ "total": 344 + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 320, + │ "textTokens": 24 │ }, + │ "outputTokens": 344, │ "raw": { │ "completion_tokens": 344, │ "completion_tokens_details": { @@ -323,15 +334,22 @@ span_tree: │ "cached_tokens": 0 │ }, │ "total_tokens": 1386 - │ } + │ }, + │ "totalTokens": 1386 │ } │ } │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", │ "model": "gpt-5-nano", │ "provider": "openai.chat" │ } │ metrics: { │ "completion_tokens": 344, + │ "prompt_cached_tokens": 0, │ "prompt_tokens": 1042, │ "tokens": 1386 │ } @@ -344,15 +362,18 @@ span_tree: │ "condition": "sunny", │ "degreesC": 21 │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } └── doStream [llm] input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ { "content": [ { @@ -394,8 +415,9 @@ span_tree: "role": "tool" } ], - "toolChoice": { - "type": "auto" + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" }, "tools": [ { @@ -634,23 +656,33 @@ span_tree: ] } output: { - "finishReason": { - "raw": "stop", - "unified": "stop" + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 192, + "textTokens": 18 }, + "outputTokens": 210, "raw": { "completion_tokens": 210, "completion_tokens_details": { @@ -663,15 +695,22 @@ span_tree: "cached_tokens": 0 }, "total_tokens": 1297 - } + }, + "totalTokens": 1297 } } metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", "model": "gpt-5-nano", "provider": "openai.chat" } metrics: { "completion_tokens": 210, + "prompt_cached_tokens": 0, "prompt_tokens": 1087, "tokens": 1297 } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.json new file mode 100644 index 000000000..2c681de25 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 18, + "total": 274 + }, + "raw": { + "completion_tokens": 274, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1361 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 274, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1361 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2683 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.txt new file mode 100644 index 000000000..78a998e7f --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2683 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 18, + "total": 274 + }, + "raw": { + "completion_tokens": 274, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1361 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 256, + "completion_tokens": 274, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1361 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.json new file mode 100644 index 000000000..4ce3a2b17 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 320, + "text": 24, + "total": 344 + }, + "raw": { + "completion_tokens": 344, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1386 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 344, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1386 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 18, + "total": 274 + }, + "raw": { + "completion_tokens": 274, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1361 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 274, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1361 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.18.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 576, + "completion_tokens": 618, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 576, + "time_to_first_token": 0, + "tokens": 2747 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.txt new file mode 100644 index 000000000..de1f3b666 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.18.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 576, + "completion_tokens": 618, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 576, + "time_to_first_token": 0, + "tokens": 2747 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 320, + │ "text": 24, + │ "total": 344 + │ }, + │ "raw": { + │ "completion_tokens": 344, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 320, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1386 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 320, + │ "completion_tokens": 344, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 320, + │ "time_to_first_token": 0, + │ "tokens": 1386 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 256, + "text": 18, + "total": 274 + }, + "raw": { + "completion_tokens": 274, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1361 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 256, + "completion_tokens": 274, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1361 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.json new file mode 100644 index 000000000..60368e288 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 448, + "text": 24, + "total": 472 + }, + "raw": { + "completion_tokens": 472, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 448, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1514 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 448, + "completion_tokens": 472, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 448, + "time_to_first_token": 0, + "tokens": 1514 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 640, + "completion_tokens": 682, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 640, + "time_to_first_token": 0, + "tokens": 2811 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.txt new file mode 100644 index 000000000..8b4dc2750 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 640, + "completion_tokens": 682, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 640, + "time_to_first_token": 0, + "tokens": 2811 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 448, + │ "text": 24, + │ "total": 472 + │ }, + │ "raw": { + │ "completion_tokens": 472, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 448, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1514 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 448, + │ "completion_tokens": 472, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 448, + │ "time_to_first_token": 0, + │ "tokens": 1514 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.json new file mode 100644 index 000000000..29f3f51a1 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.json @@ -0,0 +1,736 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 + }, + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 192, + "textTokens": 24 + }, + "outputTokens": 216, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + }, + "totalTokens": 1258 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.18.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2491 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.txt new file mode 100644 index 000000000..f153d9848 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.txt @@ -0,0 +1,716 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.18.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2491 + } + ├── doStream [llm] + │ input: { + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "content": [ + │ { + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, + │ "usage": { + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 + │ }, + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 192, + │ "textTokens": 24 + │ }, + │ "outputTokens": 216, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ }, + │ "totalTokens": 1258 + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } + └── doStream [llm] + input: { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.json new file mode 100644 index 000000000..6aa5672b0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 320, + "text": 24, + "total": 344 + }, + "raw": { + "completion_tokens": 344, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1386 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 344, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1386 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2683 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.txt new file mode 100644 index 000000000..39efb478b --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2683 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 320, + │ "text": 24, + │ "total": 344 + │ }, + │ "raw": { + │ "completion_tokens": 344, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 320, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1386 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 320, + │ "completion_tokens": 344, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 320, + │ "time_to_first_token": 0, + │ "tokens": 1386 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.json new file mode 100644 index 000000000..3d2ccc456 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 192, + "text": 24, + "total": 216 + }, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.19.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 2491 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.txt new file mode 100644 index 000000000..9ba33fd26 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.19.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 320, + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 2491 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 192, + │ "text": 24, + │ "total": 216 + │ }, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 192, + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 192, + │ "time_to_first_token": 0, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.json new file mode 100644 index 000000000..900434445 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 320, + "text": 24, + "total": 344 + }, + "raw": { + "completion_tokens": 344, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1386 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 344, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1386 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 64, + "text": 18, + "total": 82 + }, + "raw": { + "completion_tokens": 82, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 64, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1169 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 64, + "completion_tokens": 82, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 64, + "time_to_first_token": 0, + "tokens": 1169 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.txt new file mode 100644 index 000000000..2e61e7f18 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 320, + │ "text": 24, + │ "total": 344 + │ }, + │ "raw": { + │ "completion_tokens": 344, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 320, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1386 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 320, + │ "completion_tokens": 344, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 320, + │ "time_to_first_token": 0, + │ "tokens": 1386 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 64, + "text": 18, + "total": 82 + }, + "raw": { + "completion_tokens": 82, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 64, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1169 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 64, + "completion_tokens": 82, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 64, + "time_to_first_token": 0, + "tokens": 1169 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.json new file mode 100644 index 000000000..e7e6bfae0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.json @@ -0,0 +1,736 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 + }, + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 256, + "textTokens": 24 + }, + "outputTokens": 280, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + }, + "totalTokens": 1322 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.19.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2555 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.txt new file mode 100644 index 000000000..6700fe731 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.txt @@ -0,0 +1,716 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.19.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2555 + } + ├── doStream [llm] + │ input: { + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "content": [ + │ { + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, + │ "usage": { + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 + │ }, + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 256, + │ "textTokens": 24 + │ }, + │ "outputTokens": 280, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ }, + │ "totalTokens": 1322 + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } + └── doStream [llm] + input: { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.json new file mode 100644 index 000000000..6cf811fa2 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 192, + "text": 24, + "total": 216 + }, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2555 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.txt new file mode 100644 index 000000000..1a020a594 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2555 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 192, + │ "text": 24, + │ "total": 216 + │ }, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 192, + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 192, + │ "time_to_first_token": 0, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.json new file mode 100644 index 000000000..2f5203aa0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.json @@ -0,0 +1,922 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 320, + "text": 24, + "total": 344 + }, + "raw": { + "completion_tokens": 344, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1386 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 344, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1386 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 64, + "text": 18, + "total": 82 + }, + "raw": { + "completion_tokens": 82, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 64, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1169 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 64, + "completion_tokens": 82, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 64, + "time_to_first_token": 0, + "tokens": 1169 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.19.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.txt new file mode 100644 index 000000000..cfcd68142 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.txt @@ -0,0 +1,902 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.19.0", + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 384, + "completion_tokens": 426, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 384, + "time_to_first_token": 0, + "tokens": 2555 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 320, + │ "text": 24, + │ "total": 344 + │ }, + │ "raw": { + │ "completion_tokens": 344, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 320, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1386 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 320, + │ "completion_tokens": 344, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 320, + │ "time_to_first_token": 0, + │ "tokens": 1386 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 64, + "text": 18, + "total": 82 + }, + "raw": { + "completion_tokens": 82, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 64, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1169 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 64, + "completion_tokens": 82, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 64, + "time_to_first_token": 0, + "tokens": 1169 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.json new file mode 100644 index 000000000..eafb3fbdb --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.json @@ -0,0 +1,921 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 25, + "total": 281 + }, + "raw": { + "completion_tokens": 281, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1323 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 281, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1323 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 0, + "text": 12, + "total": 12 + }, + "raw": { + "completion_tokens": 12, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1099 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 0, + "completion_tokens": 12, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 0, + "time_to_first_token": 0, + "tokens": 1099 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 293, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 2422 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.txt new file mode 100644 index 000000000..76c6c0192 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.txt @@ -0,0 +1,901 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_reasoning_tokens": 256, + "completion_tokens": 293, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 2422 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 25, + │ "total": 281 + │ }, + │ "raw": { + │ "completion_tokens": 281, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1323 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 281, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1323 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 0, + "text": 12, + "total": 12 + }, + "raw": { + "completion_tokens": 12, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1099 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 0, + "completion_tokens": 12, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 0, + "time_to_first_token": 0, + "tokens": 1099 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.json new file mode 100644 index 000000000..300093d33 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.json @@ -0,0 +1,736 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 + }, + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 192, + "textTokens": 24 + }, + "outputTokens": 216, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + }, + "totalTokens": 1258 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.19.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2491 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.txt new file mode 100644 index 000000000..6b7ecae7a --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.txt @@ -0,0 +1,716 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.19.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2491 + } + ├── doStream [llm] + │ input: { + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "content": [ + │ { + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, + │ "usage": { + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 + │ }, + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 192, + │ "textTokens": 24 + │ }, + │ "outputTokens": 216, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ }, + │ "totalTokens": 1258 + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } + └── doStream [llm] + input: { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.json new file mode 100644 index 000000000..abba8a2b5 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 192, + "text": 24, + "total": 216 + }, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2491 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.txt new file mode 100644 index 000000000..c91b928b1 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2491 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 192, + │ "text": 24, + │ "total": 216 + │ }, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 192, + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 192, + │ "time_to_first_token": 0, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 128, + "text": 18, + "total": 146 + }, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 128, + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 128, + "time_to_first_token": 0, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-auto.span-tree.json new file mode 100644 index 000000000..8dd2752cf --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-auto.span-tree.json @@ -0,0 +1,736 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 + }, + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 320, + "textTokens": 24 + }, + "outputTokens": 344, + "raw": { + "completion_tokens": 344, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1386 + }, + "totalTokens": 1386 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 344, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "tokens": 1386 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 192, + "textTokens": 18 + }, + "outputTokens": 210, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + }, + "totalTokens": 1297 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.20.1", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2683 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-auto.span-tree.txt new file mode 100644 index 000000000..a23a642d6 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-auto.span-tree.txt @@ -0,0 +1,716 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.20.1", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2683 + } + ├── doStream [llm] + │ input: { + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "content": [ + │ { + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, + │ "usage": { + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 + │ }, + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 320, + │ "textTokens": 24 + │ }, + │ "outputTokens": 344, + │ "raw": { + │ "completion_tokens": 344, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 320, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1386 + │ }, + │ "totalTokens": 1386 + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_tokens": 344, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "tokens": 1386 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } + └── doStream [llm] + input: { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 192, + "textTokens": 18 + }, + "outputTokens": 210, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + }, + "totalTokens": 1297 + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-manual.span-tree.json new file mode 100644 index 000000000..6aa5672b0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 320, + "text": 24, + "total": 344 + }, + "raw": { + "completion_tokens": 344, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1386 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 344, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1386 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2683 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-manual.span-tree.txt new file mode 100644 index 000000000..39efb478b --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-1-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 554, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2683 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 320, + │ "text": 24, + │ "total": 344 + │ }, + │ "raw": { + │ "completion_tokens": 344, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 320, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1386 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 320, + │ "completion_tokens": 344, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 320, + │ "time_to_first_token": 0, + │ "tokens": 1386 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-auto.span-tree.json new file mode 100644 index 000000000..a55e6532a --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-auto.span-tree.json @@ -0,0 +1,736 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 + }, + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 256, + "textTokens": 25 + }, + "outputTokens": 281, + "raw": { + "completion_tokens": 281, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1323 + }, + "totalTokens": 1323 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 281, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "tokens": 1323 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.20.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 427, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2556 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-auto.span-tree.txt new file mode 100644 index 000000000..b1d8405fe --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-auto.span-tree.txt @@ -0,0 +1,716 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.20.0", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 427, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2556 + } + ├── doStream [llm] + │ input: { + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "content": [ + │ { + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, + │ "usage": { + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 + │ }, + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 256, + │ "textTokens": 25 + │ }, + │ "outputTokens": 281, + │ "raw": { + │ "completion_tokens": 281, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1323 + │ }, + │ "totalTokens": 1323 + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_tokens": 281, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "tokens": 1323 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } + └── doStream [llm] + input: { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-manual.span-tree.json new file mode 100644 index 000000000..c832f6d2a --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 320, + "text": 18, + "total": 338 + }, + "raw": { + "completion_tokens": 338, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1425 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 320, + "completion_tokens": 338, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1425 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 618, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2747 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-manual.span-tree.txt new file mode 100644 index 000000000..485685c27 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 618, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2747 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 320, + "text": 18, + "total": 338 + }, + "raw": { + "completion_tokens": 338, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 320, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1425 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 320, + "completion_tokens": 338, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 320, + "time_to_first_token": 0, + "tokens": 1425 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-auto.span-tree.json new file mode 100644 index 000000000..53c6b05c0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-auto.span-tree.json @@ -0,0 +1,736 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "finishReason": "tool-calls", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1042 + }, + "inputTokens": 1042, + "outputTokenDetails": { + "reasoningTokens": 192, + "textTokens": 24 + }, + "outputTokens": 216, + "raw": { + "completion_tokens": 216, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1258 + }, + "totalTokens": 1258 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 216, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "tokens": 1258 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "toolCallId": "", + "toolName": "lookup_weather" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.20.2", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2491 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-auto.span-tree.txt new file mode 100644 index 000000000..fd6a5781d --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-auto.span-tree.txt @@ -0,0 +1,716 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "cloudflare_think.version": "0.20.2", + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 362, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2491 + } + ├── doStream [llm] + │ input: { + │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "messages": [ + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "model": { + │ "modelId": "gpt-5-nano", + │ "provider": "openai.chat" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "content": [ + │ { + │ "input": { + │ "city": "Vienna" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "finishReason": "tool-calls", + │ "providerMetadata": { + │ "openai": { + │ "acceptedPredictionTokens": 0, + │ "rejectedPredictionTokens": 0 + │ } + │ }, + │ "response": { + │ "id": "" + │ }, + │ "usage": { + │ "inputTokenDetails": { + │ "cacheReadTokens": 0, + │ "noCacheTokens": 1042 + │ }, + │ "inputTokens": 1042, + │ "outputTokenDetails": { + │ "reasoningTokens": 192, + │ "textTokens": 24 + │ }, + │ "outputTokens": 216, + │ "raw": { + │ "completion_tokens": 216, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 192, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1258 + │ }, + │ "totalTokens": 1258 + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "functionId": "TestThink", + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_tokens": 216, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "tokens": 1258 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "toolCallId": "", + │ "toolName": "lookup_weather" + │ } + └── doStream [llm] + input: { + "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "messages": [ + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "model": { + "modelId": "gpt-5-nano", + "provider": "openai.chat" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "content": [ + { + "text": "Vienna is sunny and 21°C.", + "type": "text" + } + ], + "finishReason": "stop", + "providerMetadata": { + "openai": { + "acceptedPredictionTokens": 0, + "rejectedPredictionTokens": 0 + } + }, + "response": { + "id": "" + }, + "usage": { + "inputTokenDetails": { + "cacheReadTokens": 0, + "noCacheTokens": 1087 + }, + "inputTokens": 1087, + "outputTokenDetails": { + "reasoningTokens": 128, + "textTokens": 18 + }, + "outputTokens": 146, + "raw": { + "completion_tokens": 146, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 128, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1233 + }, + "totalTokens": 1233 + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "functionId": "TestThink", + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_tokens": 146, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "tokens": 1233 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-manual.span-tree.json new file mode 100644 index 000000000..2cfa395c1 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-manual.span-tree.json @@ -0,0 +1,919 @@ +{ + "span_tree": [ + { + "name": "Think.runTurn", + "type": "task", + "children": [ + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "text": "", + "toolCalls": [ + { + "input": "{\"city\":\"Vienna\"}", + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1042, + "total": 1042 + }, + "outputTokens": { + "reasoning": 256, + "text": 24, + "total": 280 + }, + "raw": { + "completion_tokens": 280, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 256, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1042, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1322 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "tool_calls", + "unified": "tool-calls" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 256, + "completion_tokens": 280, + "prompt_cached_tokens": 0, + "prompt_tokens": 1042, + "reasoning_tokens": 256, + "time_to_first_token": 0, + "tokens": 1322 + } + }, + { + "name": "lookup_weather", + "type": "tool", + "children": [], + "input": { + "city": "Vienna" + }, + "output": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + }, + "metadata": { + "toolCallId": "" + } + }, + { + "name": "doStream", + "type": "llm", + "children": [], + "input": { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + }, + "output": { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + }, + "metadata": { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + }, + "metrics": { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } + } + ], + "input": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ], + "output": { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + }, + "metadata": { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + }, + "metrics": { + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2619 + } + } + ] +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-manual.span-tree.txt new file mode 100644 index 000000000..62de172a1 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-20-latest-ai7-manual.span-tree.txt @@ -0,0 +1,899 @@ +span_tree: +└── Think.runTurn [task] + input: [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + } + ] + output: { + "content": "Vienna is sunny and 21°C.", + "role": "assistant" + } + metadata: { + "braintrust": { + "integration_name": "cloudflare-think", + "sdk_language": "typescript" + }, + "model": "gpt-5-nano", + "provider": "openai.chat", + "tools": { + "bash": { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "type": "string" + }, + "script": { + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + } + }, + "delete": { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "type": "string" + }, + "recursive": { + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "edit": { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "type": "string" + }, + "old_string": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + } + }, + "find": { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + } + }, + "grep": { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "type": "boolean" + }, + "contextLines": { + "type": "number" + }, + "fixedString": { + "type": "boolean" + }, + "include": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + } + }, + "list": { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "default": "/", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "lookup_weather": { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + } + }, + "read": { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + } + }, + "write": { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + } + } + } + } + metrics: { + "completion_tokens": 490, + "prompt_cached_tokens": 0, + "prompt_tokens": 2129, + "time_to_first_token": 0, + "tokens": 2619 + } + ├── doStream [llm] + │ input: { + │ "abortSignal": "[AbortSignal]", + │ "includeRawChunks": false, + │ "prompt": [ + │ { + │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "What is the weather in Vienna?", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ } + │ ], + │ "toolChoice": { + │ "type": "auto" + │ }, + │ "tools": [ + │ { + │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Number of lines to read", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "1-indexed line number to start reading from", + │ "maximum": 9007199254740991, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "read", + │ "type": "function" + │ }, + │ { + │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "content": { + │ "description": "Content to write to the file", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "content" + │ ], + │ "type": "object" + │ }, + │ "name": "write", + │ "type": "function" + │ }, + │ { + │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "new_string": { + │ "description": "Replacement text", + │ "type": "string" + │ }, + │ "old_string": { + │ "description": "Exact text to find and replace. Empty string to create a new file.", + │ "type": "string" + │ }, + │ "path": { + │ "description": "Absolute path to the file", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "path", + │ "old_string", + │ "new_string" + │ ], + │ "type": "object" + │ }, + │ "name": "edit", + │ "type": "function" + │ }, + │ { + │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "limit": { + │ "description": "Maximum number of entries to return (default: 200)", + │ "maximum": 1000, + │ "minimum": 1, + │ "type": "integer" + │ }, + │ "offset": { + │ "description": "Number of entries to skip (for pagination)", + │ "maximum": 9007199254740991, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "path": { + │ "default": "/", + │ "description": "Absolute path to the directory to list", + │ "type": "string" + │ } + │ }, + │ "type": "object" + │ }, + │ "name": "list", + │ "type": "function" + │ }, + │ { + │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "pattern": { + │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "pattern" + │ ], + │ "type": "object" + │ }, + │ "name": "find", + │ "type": "function" + │ }, + │ { + │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "caseSensitive": { + │ "description": "If true, search is case-sensitive (default: false)", + │ "type": "boolean" + │ }, + │ "contextLines": { + │ "description": "Number of context lines around each match (default: 0)", + │ "maximum": 10, + │ "minimum": 0, + │ "type": "integer" + │ }, + │ "fixedString": { + │ "description": "If true, treat query as a literal string instead of regex", + │ "type": "boolean" + │ }, + │ "include": { + │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + │ "type": "string" + │ }, + │ "query": { + │ "description": "Search pattern (regex or fixed string)", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "query" + │ ], + │ "type": "object" + │ }, + │ "name": "grep", + │ "type": "function" + │ }, + │ { + │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "path": { + │ "description": "Absolute path to the file or directory", + │ "type": "string" + │ }, + │ "recursive": { + │ "description": "If true, remove directories and their contents recursively", + │ "type": "boolean" + │ } + │ }, + │ "required": [ + │ "path" + │ ], + │ "type": "object" + │ }, + │ "name": "delete", + │ "type": "function" + │ }, + │ { + │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "cwd": { + │ "description": "Working directory for the script. Defaults to / (the workspace root)", + │ "type": "string" + │ }, + │ "script": { + │ "description": "Bash script to run", + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "script" + │ ], + │ "type": "object" + │ }, + │ "name": "bash", + │ "type": "function" + │ }, + │ { + │ "description": "Get deterministic weather for a city.", + │ "inputSchema": { + │ "$schema": "http://json-schema.org/draft-07/schema#", + │ "additionalProperties": false, + │ "properties": { + │ "city": { + │ "type": "string" + │ } + │ }, + │ "required": [ + │ "city" + │ ], + │ "type": "object" + │ }, + │ "name": "lookup_weather", + │ "type": "function" + │ } + │ ] + │ } + │ output: { + │ "finishReason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "text": "", + │ "toolCalls": [ + │ { + │ "input": "{\"city\":\"Vienna\"}", + │ "toolCallId": "", + │ "toolName": "lookup_weather", + │ "type": "tool-call" + │ } + │ ], + │ "usage": { + │ "inputTokens": { + │ "cacheRead": 0, + │ "noCache": 1042, + │ "total": 1042 + │ }, + │ "outputTokens": { + │ "reasoning": 256, + │ "text": 24, + │ "total": 280 + │ }, + │ "raw": { + │ "completion_tokens": 280, + │ "completion_tokens_details": { + │ "accepted_prediction_tokens": 0, + │ "reasoning_tokens": 256, + │ "rejected_prediction_tokens": 0 + │ }, + │ "prompt_tokens": 1042, + │ "prompt_tokens_details": { + │ "cached_tokens": 0 + │ }, + │ "total_tokens": 1322 + │ } + │ } + │ } + │ metadata: { + │ "braintrust": { + │ "integration_name": "ai-sdk", + │ "sdk_language": "typescript" + │ }, + │ "finish_reason": { + │ "raw": "tool_calls", + │ "unified": "tool-calls" + │ }, + │ "model": "gpt-5-nano", + │ "provider": "openai.chat" + │ } + │ metrics: { + │ "completion_reasoning_tokens": 256, + │ "completion_tokens": 280, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 1042, + │ "reasoning_tokens": 256, + │ "time_to_first_token": 0, + │ "tokens": 1322 + │ } + ├── lookup_weather [tool] + │ input: { + │ "city": "Vienna" + │ } + │ output: { + │ "city": "Vienna", + │ "condition": "sunny", + │ "degreesC": 21 + │ } + │ metadata: { + │ "toolCallId": "" + │ } + └── doStream [llm] + input: { + "abortSignal": "[AbortSignal]", + "includeRawChunks": false, + "prompt": [ + { + "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", + "role": "system" + }, + { + "content": [ + { + "text": "What is the weather in Vienna?", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "input": { + "city": "Vienna" + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-call" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "output": { + "type": "json", + "value": { + "city": "Vienna", + "condition": "sunny", + "degreesC": 21 + } + }, + "toolCallId": "", + "toolName": "lookup_weather", + "type": "tool-result" + } + ], + "role": "tool" + } + ], + "toolChoice": { + "type": "auto" + }, + "tools": [ + { + "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Number of lines to read", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "1-indexed line number to start reading from", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read", + "type": "function" + }, + { + "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write", + "type": "function" + }, + { + "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "new_string": { + "description": "Replacement text", + "type": "string" + }, + "old_string": { + "description": "Exact text to find and replace. Empty string to create a new file.", + "type": "string" + }, + "path": { + "description": "Absolute path to the file", + "type": "string" + } + }, + "required": [ + "path", + "old_string", + "new_string" + ], + "type": "object" + }, + "name": "edit", + "type": "function" + }, + { + "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "limit": { + "description": "Maximum number of entries to return (default: 200)", + "maximum": 1000, + "minimum": 1, + "type": "integer" + }, + "offset": { + "description": "Number of entries to skip (for pagination)", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "path": { + "default": "/", + "description": "Absolute path to the directory to list", + "type": "string" + } + }, + "type": "object" + }, + "name": "list", + "type": "function" + }, + { + "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pattern": { + "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "find", + "type": "function" + }, + { + "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "caseSensitive": { + "description": "If true, search is case-sensitive (default: false)", + "type": "boolean" + }, + "contextLines": { + "description": "Number of context lines around each match (default: 0)", + "maximum": 10, + "minimum": 0, + "type": "integer" + }, + "fixedString": { + "description": "If true, treat query as a literal string instead of regex", + "type": "boolean" + }, + "include": { + "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", + "type": "string" + }, + "query": { + "description": "Search pattern (regex or fixed string)", + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "name": "grep", + "type": "function" + }, + { + "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "path": { + "description": "Absolute path to the file or directory", + "type": "string" + }, + "recursive": { + "description": "If true, remove directories and their contents recursively", + "type": "boolean" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "delete", + "type": "function" + }, + { + "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cwd": { + "description": "Working directory for the script. Defaults to / (the workspace root)", + "type": "string" + }, + "script": { + "description": "Bash script to run", + "type": "string" + } + }, + "required": [ + "script" + ], + "type": "object" + }, + "name": "bash", + "type": "function" + }, + { + "description": "Get deterministic weather for a city.", + "inputSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "city": { + "type": "string" + } + }, + "required": [ + "city" + ], + "type": "object" + }, + "name": "lookup_weather", + "type": "function" + } + ] + } + output: { + "finishReason": { + "raw": "stop", + "unified": "stop" + }, + "text": "Vienna is sunny and 21°C.", + "toolCalls": [], + "usage": { + "inputTokens": { + "cacheRead": 0, + "noCache": 1087, + "total": 1087 + }, + "outputTokens": { + "reasoning": 192, + "text": 18, + "total": 210 + }, + "raw": { + "completion_tokens": 210, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "reasoning_tokens": 192, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens": 1087, + "prompt_tokens_details": { + "cached_tokens": 0 + }, + "total_tokens": 1297 + } + } + } + metadata: { + "braintrust": { + "integration_name": "ai-sdk", + "sdk_language": "typescript" + }, + "finish_reason": { + "raw": "stop", + "unified": "stop" + }, + "model": "gpt-5-nano", + "provider": "openai.chat" + } + metrics: { + "completion_reasoning_tokens": 192, + "completion_tokens": 210, + "prompt_cached_tokens": 0, + "prompt_tokens": 1087, + "reasoning_tokens": 192, + "time_to_first_token": 0, + "tokens": 1297 + } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts b/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts index f6b6d3db4..8452a8557 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts +++ b/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts @@ -6,10 +6,7 @@ import { withScenarioHarness, type ScenarioRunContext, } from "../../helpers/scenario-harness"; -import { - matchSpanTreeSnapshot, - type SpanTreeFields, -} from "../../helpers/span-tree"; +import { matchSpanTreeSnapshot, spanTreeFields } from "../../helpers/span-tree"; import { findChildSpans, findLatestSpan } from "../../helpers/trace-selectors"; type ScenarioRunner = (harness: { @@ -28,6 +25,7 @@ export function defineCloudflareThinkAssertions(options: { snapshotName: string; testFileUrl: string; timeoutMs: number; + usesV7Telemetry: boolean; }): void { const timeoutMs = effectiveScenarioTimeoutMs(options.timeoutMs); const snapshotPath = resolveFileSnapshotPath( @@ -85,13 +83,24 @@ export function defineCloudflareThinkAssertions(options: { expect(span.span.type).toBe("llm"); expect(span.span.parentIds).toEqual([task?.span.id]); expect(span.input).toEqual( - expect.objectContaining({ prompt: expect.any(Array) }), + expect.objectContaining( + options.usesV7Telemetry + ? { messages: expect.any(Array) } + : { prompt: expect.any(Array) }, + ), ); expect(span.output).toEqual( - expect.objectContaining({ - finishReason: expect.any(Object), - toolCalls: expect.any(Array), - }), + expect.objectContaining( + options.usesV7Telemetry + ? { + finishReason: expect.any(String), + content: expect.any(Array), + } + : { + finishReason: expect.any(Object), + toolCalls: expect.any(Array), + }, + ), ); expect(span.row.metadata).toMatchObject({ model: "gpt-5-nano", @@ -136,7 +145,7 @@ export function defineCloudflareThinkAssertions(options: { await matchSpanTreeSnapshot( [...latestBySpanId.values()].map((event) => ({ event, - fields: stableThinkSpanFields(event), + fields: { ...spanTreeFields(event), context: event.row.context }, })), snapshotPath, ); @@ -153,40 +162,3 @@ function expectPositiveTokenMetrics( (metrics?.prompt_tokens ?? 0) + (metrics?.completion_tokens ?? 0), ); } - -function stableThinkSpanFields(event: CapturedLogEvent): SpanTreeFields { - const metadata = event.metadata; - const metrics = event.metrics; - const isTask = event.span.name === "Think.runTurn"; - - return { - input: isTask ? taskUserInput(event.input) : event.input, - output: event.output, - metadata: metadata - ? { - braintrust: isTask ? metadata.braintrust : undefined, - model: metadata.model, - provider: metadata.provider, - } - : undefined, - metrics: metrics - ? { - completion_tokens: metrics.completion_tokens, - prompt_tokens: metrics.prompt_tokens, - tokens: metrics.tokens, - } - : undefined, - }; -} - -function taskUserInput(input: unknown): unknown { - return Array.isArray(input) - ? input.filter( - (message) => - typeof message === "object" && - message !== null && - "role" in message && - message.role === "user", - ) - : input; -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/package.json b/e2e/scenarios/cloudflare-think-instrumentation/package.json index c5efd5067..47f778000 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/package.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/package.json @@ -5,48 +5,85 @@ "braintrustScenario": { "bump": { "dependencies": { - "cloudflare-think-v0-latest": { + "cloudflare-think-v0-13-latest-ai6": { "package": "@cloudflare/think", - "range": ">=0.13.0 <0.14.0" + "range": ">=0.13.0 <0.14.0", + "targetManifest": "versions/ai6/package.json", + "targetDependency": "cloudflare-think-v0-13-latest" + }, + "cloudflare-think-v0-14-latest-ai6": { + "package": "@cloudflare/think", + "range": ">=0.14.0 <0.15.0", + "targetManifest": "versions/ai6/package.json", + "targetDependency": "cloudflare-think-v0-14-latest" + }, + "cloudflare-think-v0-15-latest-ai6": { + "package": "@cloudflare/think", + "range": ">=0.15.0 <0.16.0", + "targetManifest": "versions/ai6/package.json", + "targetDependency": "cloudflare-think-v0-15-latest" + }, + "cloudflare-think-v0-16-latest-ai6": { + "package": "@cloudflare/think", + "range": ">=0.16.0 <0.17.0", + "targetManifest": "versions/ai6/package.json", + "targetDependency": "cloudflare-think-v0-16-latest" + }, + "cloudflare-think-v0-17-latest-ai6": { + "package": "@cloudflare/think", + "range": ">=0.17.0 <0.18.0", + "targetManifest": "versions/ai6/package.json", + "targetDependency": "cloudflare-think-v0-17-latest" + }, + "cloudflare-think-v0-18-latest-ai6": { + "package": "@cloudflare/think", + "range": ">=0.18.0 <0.19.0", + "targetManifest": "versions/ai6/package.json", + "targetDependency": "cloudflare-think-v0-18-latest" + }, + "cloudflare-think-v0-19-latest-ai6": { + "package": "@cloudflare/think", + "range": ">=0.19.0 <0.20.0", + "targetManifest": "versions/ai6/package.json", + "targetDependency": "cloudflare-think-v0-19-latest" + }, + "cloudflare-think-v0-15-latest-ai7": { + "package": "@cloudflare/think", + "range": ">=0.15.0 <0.16.0", + "targetManifest": "versions/ai7/package.json", + "targetDependency": "cloudflare-think-v0-15-latest" + }, + "cloudflare-think-v0-16-latest-ai7": { + "package": "@cloudflare/think", + "range": ">=0.16.0 <0.17.0", + "targetManifest": "versions/ai7/package.json", + "targetDependency": "cloudflare-think-v0-16-latest" + }, + "cloudflare-think-v0-17-latest-ai7": { + "package": "@cloudflare/think", + "range": ">=0.17.0 <0.18.0", + "targetManifest": "versions/ai7/package.json", + "targetDependency": "cloudflare-think-v0-17-latest" + }, + "cloudflare-think-v0-18-latest-ai7": { + "package": "@cloudflare/think", + "range": ">=0.18.0 <0.19.0", + "targetManifest": "versions/ai7/package.json", + "targetDependency": "cloudflare-think-v0-18-latest" + }, + "cloudflare-think-v0-19-latest-ai7": { + "package": "@cloudflare/think", + "range": ">=0.19.0 <0.20.0", + "targetManifest": "versions/ai7/package.json", + "targetDependency": "cloudflare-think-v0-19-latest" + }, + "cloudflare-think-v0-20-latest-ai7": { + "package": "@cloudflare/think", + "range": ">=0.20.0 <0.21.0", + "targetManifest": "versions/ai7/package.json", + "targetDependency": "cloudflare-think-v0-20-latest" } } } - }, - "dependencies": { - "@ai-sdk/openai": "3.0.80", - "@cloudflare/vite-plugin": "1.45.1", - "agents": "0.17.4", - "ai": "6.0.202", - "ai-unwrapped": "npm:ai@6.0.202", - "cloudflare-think-v0": "npm:@cloudflare/think@0.13.0", - "cloudflare-think-v0-latest": "npm:@cloudflare/think@0.13.0", - "dc-browser": "1.0.4", - "vite": "7.3.5", - "wrangler": "4.112.0", - "zod": "4.3.6" - }, - "pnpm": { - "overrides": { - "esbuild@<0.28.1": "^0.28.1", - "ip-address@<10.2.2": "10.7.1", - "sharp@<0.35.0": "0.35.5", - "@hono/node-server@<2.0.5": "^2.0.10", - "brace-expansion@5.0.7": "5.0.12", - "undici@<7.29.0": "7.29.1", - "hono@<4.12.34": "4.13.7", - "nanoid@<3.3.18": "^3.3.18", - "fast-uri@<3.1.5": "3.1.8", - "postcss@<8.5.23": "^8.5.23", - "fast-uri@>=3.0.0 <3.1.8": "3.1.8", - "ip-address@>=10.0.0 <10.7.1": "10.7.1", - "undici@>=7.0.0 <7.29.1": "7.29.1", - "brace-expansion@>=5.0.0 <5.0.12": "5.0.12", - "hono@>=4.0.0 <4.13.7": "4.13.7", - "proxy-addr@>=2.0.0 <2.0.8": "2.0.8", - "source-map-js@>=1.0.0 <1.2.2": "1.2.2", - "smol-toml@>=1.0.0 <1.9.0": "1.9.0", - "sharp@>=0.35.0 <0.35.5": "0.35.5", - "@modelcontextprotocol/sdk@>=1.0.0 <1.31.0": "1.31.0" - } } } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/pnpm-lock.yaml b/e2e/scenarios/cloudflare-think-instrumentation/pnpm-lock.yaml index 2f488b377..9b60ae178 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/pnpm-lock.yaml +++ b/e2e/scenarios/cloudflare-think-instrumentation/pnpm-lock.yaml @@ -4,4712 +4,6 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false -overrides: - esbuild@<0.28.1: ^0.28.1 - ip-address@<10.2.2: 10.7.1 - sharp@<0.35.0: 0.35.5 - '@hono/node-server@<2.0.5': ^2.0.10 - brace-expansion@5.0.7: 5.0.12 - undici@<7.29.0: 7.29.1 - hono@<4.12.34: 4.13.7 - nanoid@<3.3.18: ^3.3.18 - fast-uri@<3.1.5: 3.1.8 - postcss@<8.5.23: ^8.5.23 - fast-uri@>=3.0.0 <3.1.8: 3.1.8 - ip-address@>=10.0.0 <10.7.1: 10.7.1 - undici@>=7.0.0 <7.29.1: 7.29.1 - brace-expansion@>=5.0.0 <5.0.12: 5.0.12 - hono@>=4.0.0 <4.13.7: 4.13.7 - proxy-addr@>=2.0.0 <2.0.8: 2.0.8 - source-map-js@>=1.0.0 <1.2.2: 1.2.2 - smol-toml@>=1.0.0 <1.9.0: 1.9.0 - sharp@>=0.35.0 <0.35.5: 0.35.5 - '@modelcontextprotocol/sdk@>=1.0.0 <1.31.0': 1.31.0 - importers: - .: - dependencies: - '@ai-sdk/openai': - specifier: 3.0.80 - version: 3.0.80(zod@4.3.6) - '@cloudflare/vite-plugin': - specifier: 1.45.1 - version: 1.45.1(vite@7.3.5(yaml@2.9.0))(wrangler@4.112.0) - agents: - specifier: 0.17.4 - version: 0.17.4(@babel/core@8.0.1)(@babel/runtime@7.29.7)(ai@6.0.202(zod@4.3.6))(chat@4.34.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.1.0)(react@19.2.7)(rolldown@1.2.0)(vite@7.3.5(yaml@2.9.0))(zod@4.3.6) - ai: - specifier: 6.0.202 - version: 6.0.202(zod@4.3.6) - ai-unwrapped: - specifier: npm:ai@6.0.202 - version: ai@6.0.202(zod@4.3.6) - cloudflare-think-v0: - specifier: npm:@cloudflare/think@0.13.0 - version: '@cloudflare/think@0.13.0(@ai-sdk/provider@3.0.14)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.17.4(@babel/core@8.0.1)(@babel/runtime@7.29.7)(ai@6.0.202(zod@4.3.6))(chat@4.34.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.1.0)(react@19.2.7)(rolldown@1.2.0)(vite@7.3.5(yaml@2.9.0))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.2.7)(vite@7.3.5(yaml@2.9.0))(zod@4.3.6)' - cloudflare-think-v0-latest: - specifier: npm:@cloudflare/think@0.13.0 - version: '@cloudflare/think@0.13.0(@ai-sdk/provider@3.0.14)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.17.4(@babel/core@8.0.1)(@babel/runtime@7.29.7)(ai@6.0.202(zod@4.3.6))(chat@4.34.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.1.0)(react@19.2.7)(rolldown@1.2.0)(vite@7.3.5(yaml@2.9.0))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.2.7)(vite@7.3.5(yaml@2.9.0))(zod@4.3.6)' - dc-browser: - specifier: 1.0.4 - version: 1.0.4 - vite: - specifier: 7.3.5 - version: 7.3.5(yaml@2.9.0) - wrangler: - specifier: 4.112.0 - version: 4.112.0 - zod: - specifier: 4.3.6 - version: 4.3.6 - -packages: - - '@ai-sdk/anthropic@3.0.98': - resolution: {integrity: sha512-JSHw0m15tXsdZWaV64UOjbHFKHGsPVUi9jYApNaz2QOBm987vl+l9aUFnlN1OWmFvDNMIhAPVOYRsFwjK0by/w==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/gateway@3.0.128': - resolution: {integrity: sha512-t9Dyqk5thSmIzsNvVTQtZZiO3xqKGkk1hX3+GNpYmro+GuEdW+E6mKFHihb9Y1vCEt3rEyd4pbGUcin4D57FfQ==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/openai@3.0.80': - resolution: {integrity: sha512-u3EfYbBG4YS/U2eOGH0yv8lPRwDj25X3sTluUKMYEwOLTZzWYv0IPtrpO7tPEra0QU4oq5Gpg49/FGFSrzE4vA==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/provider-utils@4.0.28': - resolution: {integrity: sha512-nCtGJY43Kqwoyk0rYLj80a3eyXxcaWwyu+lYZDHgY+U6JbYYyvRdRTSy+XCDIB91rFH0Ul0eMDHmDr+YMYtrSw==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/provider-utils@4.0.35': - resolution: {integrity: sha512-bjYld/2KGPLt78kpqbya+fD4LYS7BqVQJyUjE3qAHrYB0FR2Q90BaWEVIBZaguTWXf/A8L6uG1zO1v9TxVlGWg==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/provider-utils@4.0.40': - resolution: {integrity: sha512-OL5IrpUm9Y8Dwy+w/vvFwPotS6m52O9W0op2oXgXdCROMJIBalBI0oro6OIBYkPxvm5Xg02GSkoQN25RlR0bnw==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/provider@3.0.10': - resolution: {integrity: sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw==} - engines: {node: '>=18'} - - '@ai-sdk/provider@3.0.13': - resolution: {integrity: sha512-ZPtVYt5QIJzOta1kdUiDuCx4HhFkvNPv/rvmZ2b1iXwybYjJsCnNYR4PAw4kW7rgVfDARvHXcU64efWuqNp6bw==} - engines: {node: '>=18'} - - '@ai-sdk/provider@3.0.14': - resolution: {integrity: sha512-5X1k57JBJ4H7H1QjX7CnJYAB1I19r/trVZTMcSms7/kLNZ8RaU4Nt2agcwZzv82Hfx6Q7/TOLU7agAKeFfc8cA==} - engines: {node: '>=18'} - - '@babel/code-frame@8.0.0': - resolution: {integrity: sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/compat-data@8.0.0': - resolution: {integrity: sha512-DOjnob/cXOUgDOozCDeq/aK2p5y8dUIVdf6tNhEV1HQRd6I8aQ4f4fbtHRVEvb6lP3BGomrKHiS8ICAASSVQSw==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/core@8.0.1': - resolution: {integrity: sha512-5FgxM4dLQpMJHSiVATk8foW263dVHQHBVpXYiimNECVWG01f4nFyEbQixeT6Mwvg7TayREJ2gpKl3o2RoMdnqw==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/generator@8.0.0': - resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-annotate-as-pure@8.0.0': - resolution: {integrity: sha512-NSpMkMsvvZqzThJ0p1B02cbtA2ObEyfBvq950bmNkyxsxvcxwhvvCB036rKhlEnuBBo30bOrk13u3FzlKSoRrw==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-compilation-targets@8.0.0': - resolution: {integrity: sha512-JwculLABZvyPvyLBpwU/E/IbH2uM3mnxNtIJpxnIfb24y1PrdVxK5Dqjle4DpgqpGRnwgC7G8IkzPdSXZrO1Ew==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-create-class-features-plugin@8.0.1': - resolution: {integrity: sha512-++t3ZktzlLmASAxIlxeXQK9Z2YwUafYGYcvGBFevqOqt16HozVHStUoQvWD09fzAZOb/uJGpUTBuGK41AJAuOA==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/helper-globals@8.0.0': - resolution: {integrity: sha512-lLozHOM6sWWlxNo8CYqHy4MBZeTvHXNgVPBfPOGsjPKUzHC2Az9QwB6gxdQmpwHl6GlQtbGgS+lj5887guDiLw==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-member-expression-to-functions@8.0.0': - resolution: {integrity: sha512-xkXrMbtk87Gk7+oKBVmBc6EORg/Qwx++AHESldmHkpvG8wgccdhJJFwrzqlF382Fk8wfXhJHWE/g/43QvEGNPQ==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-optimise-call-expression@8.0.0': - resolution: {integrity: sha512-3W6satvtPuCUkUx63S2jMoW9EQNYkADgs1HTfufmL7gCmAulHMKupA/12WNz4A0GMMFn/YnWWwqOT9IZrJHQjg==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-plugin-utils@8.0.1': - resolution: {integrity: sha512-3PKFgjTyPlhFhorfP+SjKQxLViIL++zWjFOO4hGriYU+Bsm983DxEM1JmDRJVWXV0O9npu+xXRqz7Pbd3mh70g==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/helper-replace-supers@8.0.1': - resolution: {integrity: sha512-B1SZADIcy3tmH8CmWvj4SHi/oAPom4UL3uknTc2QRNsPVLFk/sPnZvQL/8kj7Y5omvjMqie0vklvs6XM4OLW5Q==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/helper-skip-transparent-expression-wrappers@8.0.0': - resolution: {integrity: sha512-xmCA9kP3IhySsqhzwIdWGlDN/1A4cCKNBO/uwZx/3YzmDoMePwno2Q5/Bq0q+tYaKbeF940YiKV/kaW8Mzvpjw==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-string-parser@8.0.0': - resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-validator-identifier@8.0.4': - resolution: {integrity: sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-validator-option@8.0.0': - resolution: {integrity: sha512-U4Dybxh4WESWHt5XhBeExi4DrY0/DNK1aHpQbsrQXCUbFHuMweT0TpLEWKvaraV2Y6fS+ZXunsZ8zIuZIgvF2Q==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helpers@8.0.0': - resolution: {integrity: sha512-wfbi91pM3py96oIiJEz7qIpyXDytgr9zQC1HEWwlGNVRAEmItuU/0a41ZUKu1sJGyhhOIpc4t5vk4PYzt8wpsg==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/parser@8.0.4': - resolution: {integrity: sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==} - engines: {node: ^22.18.0 || >=24.11.0} - hasBin: true - - '@babel/plugin-proposal-decorators@8.0.2': - resolution: {integrity: sha512-+C6O6KKXU7BBq1GNaIkFJxrALUVGRcr+WeWm4OcuRl3h+l/CmNfcTLMrT2Lm3uvGBimBH/8pEBRrXJFLoO67Gg==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/plugin-syntax-decorators@8.0.1': - resolution: {integrity: sha512-NI+0S/6MvR6GlcQFwjDZ+WIc2qvG6TXN534lYs9llNldwW4b7Dh6KTtk030FA0xWdYGs4t1lWo+OEWN8wGB+Nw==} - engines: {node: ^22.18.0 || >=24.11.0} - peerDependencies: - '@babel/core': ^8.0.0 - - '@babel/runtime-corejs3@7.29.7': - resolution: {integrity: sha512-ppj9ouYku+RX0ljtgZd+KMO5mkM2bCqg8H2PYAFWnLsHEIKIdRojqbJ2i3eVHrisuxy7nOFCmngTDdWtUCdXUQ==} - engines: {node: '>=6.9.0'} - - '@babel/runtime@7.29.7': - resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} - engines: {node: '>=6.9.0'} - - '@babel/template@8.0.0': - resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/traverse@8.0.4': - resolution: {integrity: sha512-bZnmqzGG8UZneG1lLxBoWIH0G6Gr1D846Yu4/3XnY6FhCndMR49u26nTY08u/dAxWmLWF9vGQOuC+84FfIUoeg==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/types@8.0.4': - resolution: {integrity: sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@borewit/text-codec@0.2.2': - resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} - - '@cfworker/json-schema@4.1.1': - resolution: {integrity: sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==} - - '@cloudflare/codemode@0.4.3': - resolution: {integrity: sha512-S6LIqj/NnmFRFxm3j0tPEGMF8HQF5DpV7sQg/W+U48YmnznTKOBcbS8eiV7SxBpIITLuMBcL4KpTDm1RDL20pA==} - peerDependencies: - '@modelcontextprotocol/sdk': 1.31.0 - '@tanstack/ai': '>=0.8.0 <1.0.0' - ai: ^6.0.0 - zod: ^4.0.0 - peerDependenciesMeta: - '@modelcontextprotocol/sdk': - optional: true - '@tanstack/ai': - optional: true - ai: - optional: true - zod: - optional: true - - '@cloudflare/kv-asset-handler@0.5.0': - resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==} - engines: {node: '>=22.0.0'} - - '@cloudflare/shell@0.4.1': - resolution: {integrity: sha512-fOj7W6LJOPUppTxJ8JYSj5umEZtwz0Lf7dGYXjiRPBEtSjoASnJfMpfNqitLLeDC5qx0VIzaa/6oskMWQvUOTw==} - - '@cloudflare/think@0.13.0': - resolution: {integrity: sha512-0Zo7jjPLLUv2q4FRu9ww3GrDFCOv73NgDl19yfjVGcYzAnxphiWRNaG1Sl7bwXcfWKZBUZ4SE2ckT3WEUjqzzw==} - hasBin: true - peerDependencies: - '@ai-sdk/react': ^3.0.204 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.17.1 <1.0.0' - ai: ^6.0.182 - react: ^19.0.0 - vite: '>=6 <9' - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - vite: - optional: true - - '@cloudflare/unenv-preset@2.16.1': - resolution: {integrity: sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==} - peerDependencies: - unenv: 2.0.0-rc.24 - workerd: '>1.20260305.0 <2.0.0-0' - peerDependenciesMeta: - workerd: - optional: true - - '@cloudflare/vite-plugin@1.45.1': - resolution: {integrity: sha512-C+iDpO9pVH7IqrjdYtUV+obcTAdpiNk0OSinGEZZyd2ZWyGVjGk7iJ2p3xpMBpZuTa1I4hfAECNp0yN/8f3PIQ==} - hasBin: true - peerDependencies: - vite: ^6.1.0 || ^7.0.0 || ^8.0.0 - wrangler: ^4.112.0 - - '@cloudflare/workerd-darwin-64@1.20260714.1': - resolution: {integrity: sha512-ZWXqAN8G7Cx9hMRQuk+59ziJhR3j1F4iO+Qs8aHdfKZ3Dq5Yi/57xvkJTgCGBnW1YU/L78r8f6HEy51bwbTpNw==} - engines: {node: '>=16'} - cpu: [x64] - os: [darwin] - - '@cloudflare/workerd-darwin-arm64@1.20260714.1': - resolution: {integrity: sha512-tueWxWC3wyCbMG6zRAxsMXX0YLgrRWbiAPYFQ2uJ7dUH8G+5E7UTWaQS9B1HdJ0bpKFW1NWxhs1o2noKVFSUYg==} - engines: {node: '>=16'} - cpu: [arm64] - os: [darwin] - - '@cloudflare/workerd-linux-64@1.20260714.1': - resolution: {integrity: sha512-1VChTZRb0l0F7R4e1G5RtLKV4oFi6x+rQgxh2+yu887j3l/3TLgatuv1L8/5zhc9gKEhATTxOh0e52Rtd9dDWQ==} - engines: {node: '>=16'} - cpu: [x64] - os: [linux] - - '@cloudflare/workerd-linux-arm64@1.20260714.1': - resolution: {integrity: sha512-rMm3G+NirG2UdgHIRDdF1asNC6FqgIzZzkRG+VDhhDGcVxAQwvrMT1E38BivEvHr3G04MB4AfhcOczX0+GtRkQ==} - engines: {node: '>=16'} - cpu: [arm64] - os: [linux] - - '@cloudflare/workerd-windows-64@1.20260714.1': - resolution: {integrity: sha512-cGqnU3Hg2YZS/k3SAqrMp1DjpdsyFde72tWltdl6ZT9+SFz/Zrk/8gyTU1TcxC4YApXeNVH5TyU5cOGPgUJ0pg==} - engines: {node: '>=16'} - cpu: [x64] - os: [win32] - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - - '@emnapi/core@1.11.2': - resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==} - - '@emnapi/runtime@1.11.2': - resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} - - '@emnapi/runtime@1.11.3': - resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} - - '@emnapi/wasi-threads@1.2.2': - resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} - - '@esbuild/aix-ppc64@0.28.1': - resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.28.1': - resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.28.1': - resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.28.1': - resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.28.1': - resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.28.1': - resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.28.1': - resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.28.1': - resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.28.1': - resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.28.1': - resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.28.1': - resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.28.1': - resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.28.1': - resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.28.1': - resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.28.1': - resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.28.1': - resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.28.1': - resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.28.1': - resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.28.1': - resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.28.1': - resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.28.1': - resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.28.1': - resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.28.1': - resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.28.1': - resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.28.1': - resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.28.1': - resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@hono/node-server@2.1.0': - resolution: {integrity: sha512-XovyyCCnBzW+zKu+z/zq8hwNs4KOR5rEMAOxo2f40Q5xoOI37IMm6MIg2COOUtUApo0i6850MTBKH2u4QLGIqg==} - engines: {node: '>=20'} - peerDependencies: - hono: 4.13.7 - - '@img/colour@1.1.0': - resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} - engines: {node: '>=18'} - - '@img/sharp-darwin-arm64@0.35.5': - resolution: {integrity: sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==} - engines: {node: '>=20.9.0'} - cpu: [arm64] - os: [darwin] - - '@img/sharp-darwin-x64@0.35.5': - resolution: {integrity: sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==} - engines: {node: '>=20.9.0'} - cpu: [x64] - os: [darwin] - - '@img/sharp-freebsd-wasm32@0.35.5': - resolution: {integrity: sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==} - engines: {node: '>=20.9.0'} - os: [freebsd] - - '@img/sharp-libvips-darwin-arm64@1.3.4': - resolution: {integrity: sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==} - cpu: [arm64] - os: [darwin] - - '@img/sharp-libvips-darwin-x64@1.3.4': - resolution: {integrity: sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==} - cpu: [x64] - os: [darwin] - - '@img/sharp-libvips-linux-arm64@1.3.4': - resolution: {integrity: sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@img/sharp-libvips-linux-arm@1.3.4': - resolution: {integrity: sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@img/sharp-libvips-linux-ppc64@1.3.4': - resolution: {integrity: sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@img/sharp-libvips-linux-riscv64@1.3.4': - resolution: {integrity: sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@img/sharp-libvips-linux-s390x@1.3.4': - resolution: {integrity: sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@img/sharp-libvips-linux-x64@1.3.4': - resolution: {integrity: sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@img/sharp-libvips-linuxmusl-arm64@1.3.4': - resolution: {integrity: sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@img/sharp-libvips-linuxmusl-x64@1.3.4': - resolution: {integrity: sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@img/sharp-linux-arm64@0.35.5': - resolution: {integrity: sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==} - engines: {node: '>=20.9.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@img/sharp-linux-arm@0.35.5': - resolution: {integrity: sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==} - engines: {node: '>=20.9.0'} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@img/sharp-linux-ppc64@0.35.5': - resolution: {integrity: sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==} - engines: {node: '>=20.9.0'} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@img/sharp-linux-riscv64@0.35.5': - resolution: {integrity: sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==} - engines: {node: '>=20.9.0'} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@img/sharp-linux-s390x@0.35.5': - resolution: {integrity: sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==} - engines: {node: '>=20.9.0'} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@img/sharp-linux-x64@0.35.5': - resolution: {integrity: sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==} - engines: {node: '>=20.9.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@img/sharp-linuxmusl-arm64@0.35.5': - resolution: {integrity: sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==} - engines: {node: '>=20.9.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@img/sharp-linuxmusl-x64@0.35.5': - resolution: {integrity: sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==} - engines: {node: '>=20.9.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - '@img/sharp-wasm32@0.35.5': - resolution: {integrity: sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==} - engines: {node: '>=20.9.0'} - - '@img/sharp-webcontainers-wasm32@0.35.5': - resolution: {integrity: sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==} - engines: {node: '>=20.9.0'} - cpu: [wasm32] - - '@img/sharp-win32-arm64@0.35.5': - resolution: {integrity: sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==} - engines: {node: '>=20.9.0'} - cpu: [arm64] - os: [win32] - - '@img/sharp-win32-ia32@0.35.5': - resolution: {integrity: sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==} - engines: {node: ^20.9.0} - cpu: [ia32] - os: [win32] - - '@img/sharp-win32-x64@0.35.5': - resolution: {integrity: sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==} - engines: {node: '>=20.9.0'} - cpu: [x64] - os: [win32] - - '@jitl/quickjs-ffi-types@0.32.0': - resolution: {integrity: sha512-v9T+GQpmk43VDJ7d72sf0Nexhk+ArvtUihW27dy7lqAl0zBObFKtSBBIm5RBjwIhE8VwsPPm9PNuvPvNqLWUEg==} - - '@jitl/quickjs-wasmfile-debug-asyncify@0.32.0': - resolution: {integrity: sha512-EX8zbXwGqCgAE764M+qvkHtyXDi/FUoMBea0JnES7vCM3P7a2+EOZOjGv85wtZ2sJhI1oJ+nekmqpOODFDY+hw==} - - '@jitl/quickjs-wasmfile-debug-sync@0.32.0': - resolution: {integrity: sha512-LeYWrPGC1uNCTBWvibo3ZLJj0CSVNYUXvJpXMCmuQ5Sap2cCACc3uvGvYV4homHHBAzfw5akoTqMMS4YFRtw+Q==} - - '@jitl/quickjs-wasmfile-release-asyncify@0.32.0': - resolution: {integrity: sha512-3oSwPfja12ICz4aIblB58cuY8JlEq5Txt8Cut4VLo+LH47QN+mzCnSgnbB03hWzg1LBcc+VyyI9UOag7a1NF+Q==} - - '@jitl/quickjs-wasmfile-release-sync@0.32.0': - resolution: {integrity: sha512-BKNDI/TPBfGlLNGYpLrhcDGXmIk4xHm4MRAisOBnOzpXVn9HZWsfmMAc9WMBrAHjvvds6HOikKeaOBKdPdpVrg==} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - - '@mixmark-io/domino@2.2.0': - resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} - - '@modelcontextprotocol/sdk@1.31.0': - resolution: {integrity: sha512-UvTMgnNlnIBO/22ob2RcVGDlcvOslQs8T59+FTGdA0L27a39fdGF/EDETNtDVK4DZGpwomlsYpRdA8UXcVL/pw==} - engines: {node: '>=18'} - peerDependencies: - '@cfworker/json-schema': ^4.1.1 - zod: ^3.25 || ^4.0 - peerDependenciesMeta: - '@cfworker/json-schema': - optional: true - - '@mongodb-js/zstd@7.0.0': - resolution: {integrity: sha512-mQ2s0pYYiav+tzCDR05Zptem8Ey2v8s11lri5RKGhTtL4COVCvVCk5vtyRYNT+9L8qSfyOqqefF9UtnW8mC5jA==} - engines: {node: '>= 20.19.0'} - - '@napi-rs/wasm-runtime@1.1.6': - resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} - peerDependencies: - '@emnapi/core': ^1.7.1 - '@emnapi/runtime': ^1.7.1 - - '@nodable/entities@3.0.0': - resolution: {integrity: sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw==} - - '@opentelemetry/api@1.9.1': - resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} - engines: {node: '>=8.0.0'} - - '@oxc-project/types@0.140.0': - resolution: {integrity: sha512-h5LUOzGArYemnW1NMz/DuuQhBi96J6JL2Bk8zE4kvqxB5Sg3jxmCiH4uyOWHDkiKSt5vWlG4FIwCR/DbstcNRQ==} - - '@poppinss/colors@4.1.6': - resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} - - '@poppinss/dumper@0.6.5': - resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==} - - '@poppinss/exception@1.2.3': - resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} - - '@rolldown/binding-android-arm64@1.2.0': - resolution: {integrity: sha512-9yB1l95IrJuNGDFdOYe79vdApdz6WWBCObE+rQ2LUliYUlcyFwSYIb2xb5/Ifw7dAtMy2ZqNyd8QTSOc7duAKw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-darwin-arm64@1.2.0': - resolution: {integrity: sha512-pexNaW9ACLUOaBITOpU6qVu4VrsOFIjTv6bzgu0YUATo4eUJx0V605PxwZfndpPOn0ilqGqvGQ0M8UW0IE24jg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.2.0': - resolution: {integrity: sha512-NqKYaq0355ZmNMG4QGpxtEDxsc7tGDhjhCm4PpE0cwnBW+5Il95LJyq414niEiaKLVjnVHBEjSo1wngKxJNiFw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-freebsd-x64@1.2.0': - resolution: {integrity: sha512-3vPoHzh6eBTz9IbB0/qZdSr0Qeks2echn+I4cHu2joV74VriPDdldswksEDzrl1mBB+oPRi+67+3Ib59paxIPQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-linux-arm-gnueabihf@1.2.0': - resolution: {integrity: sha512-E6NNefZ1bUVmKJq2tJkf45J4Zyczj7qm9rUT7NY+Xo2474Y13qWAwc2tvBt0BAVbmtXR1llkxXg0Ou1jbDf2SQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.2.0': - resolution: {integrity: sha512-D+TgkdgM1vu+7/Fpf8+v0ARW+RXEP9Ccazgm8zQ4JFFd9Q7SrYQ2TakU5S5ihazQDgpKyAgZDOcIFsvoHmTZ8w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-arm64-musl@1.2.0': - resolution: {integrity: sha512-wUqdwJBbAv0APN87GecstdMUtLjjNTs0hBALpxETD73mccFxdmt/XeizXDtN5RAlBwNKmI+Tg+blect2G+8IeQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rolldown/binding-linux-ppc64-gnu@1.2.0': - resolution: {integrity: sha512-9DtF35qR9/NrfhM4oxLplCzVVjE+KKm8Pjemi0i/sdhAWkUasjmSo8WTTubNJClhSHCfyk2yeyoXDQEDPtDAAw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-s390x-gnu@1.2.0': - resolution: {integrity: sha512-RzuHrBh8X8Hntd2N4VR02QGEciq/9JhcZoTpR/Cee6otRrlILGCf3cg2ygHuih+ZebUnWmMrDX6ITI85btO6rQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-gnu@1.2.0': - resolution: {integrity: sha512-MK7L0018jjh1jR3mh21G2j1zAVcpscJBlPo2z19pRjv2XOYGRhaV4LyiD8HO6nCDdZln9IFgCMIV5yt4E3klGQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-musl@1.2.0': - resolution: {integrity: sha512-gyrxLQ9NfGb/9LoVnC4kb9miUghw1mghnkfYvNHSnVIXriabnfgGPUP4RLcJm87q3KgYz4FYUG8IDiWUT+CpSw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rolldown/binding-openharmony-arm64@1.2.0': - resolution: {integrity: sha512-/6VFMQGRmrhP77KXDC+StIxGzcNp5JOIyYtw0CQ8gPlzhpiIRucYfoM5FaFamHd5BJYIdH86yfP46l1p3WdrFA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-wasm32-wasi@1.2.0': - resolution: {integrity: sha512-rwdbUL465kisF24WEJLvP3JrEG6E5GRuIHt5wpMwHGERtHe4Wm2CIvtf5gTBgr2tGOHKh5NdKEAFS2VkOPE91g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [wasm32] - - '@rolldown/binding-win32-arm64-msvc@1.2.0': - resolution: {integrity: sha512-+5suHwRiKGmhwyUaNT8a5QbrBvLFh2DbO910TEmGRH1aSxwrCezodvGQnulv4uiWEIv1Kq4ypRsJ5+O+ry1DiA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.2.0': - resolution: {integrity: sha512-WfFv6/qGufotqBSBzBYwgpCkJBk8Nj7697LL9vTz/XWc67e0r3oewu8iMRwQj3AUL45GVD7wVsPjCsAAtW66Wg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/plugin-babel@0.2.3': - resolution: {integrity: sha512-+zEk16yGlz1F9STiRr6uG9hmIXb6nprjLczV/htGptYuLoCuxb+itZ03RKCEeOhBpDDd1NU7qF6x1VLMUp62bw==} - engines: {node: '>=22.12.0 || ^24.0.0'} - peerDependencies: - '@babel/core': ^7.29.0 || ^8.0.0-rc.1 - '@babel/plugin-transform-runtime': ^7.29.0 || ^8.0.0-rc.1 - '@babel/runtime': ^7.27.0 || ^8.0.0-rc.1 - rolldown: ^1.0.0-rc.5 - vite: ^8.0.0 - peerDependenciesMeta: - '@babel/plugin-transform-runtime': - optional: true - '@babel/runtime': - optional: true - vite: - optional: true - - '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - - '@rollup/rollup-android-arm-eabi@4.62.2': - resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.62.2': - resolution: {integrity: sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.62.2': - resolution: {integrity: sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.62.2': - resolution: {integrity: sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.62.2': - resolution: {integrity: sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.62.2': - resolution: {integrity: sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.62.2': - resolution: {integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm-musleabihf@4.62.2': - resolution: {integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==} - cpu: [arm] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-arm64-gnu@4.62.2': - resolution: {integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm64-musl@4.62.2': - resolution: {integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-loong64-gnu@4.62.2': - resolution: {integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==} - cpu: [loong64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-loong64-musl@4.62.2': - resolution: {integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==} - cpu: [loong64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-ppc64-gnu@4.62.2': - resolution: {integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-ppc64-musl@4.62.2': - resolution: {integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==} - cpu: [ppc64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-riscv64-gnu@4.62.2': - resolution: {integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-riscv64-musl@4.62.2': - resolution: {integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-s390x-gnu@4.62.2': - resolution: {integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-gnu@4.62.2': - resolution: {integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-musl@4.62.2': - resolution: {integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rollup/rollup-openbsd-x64@4.62.2': - resolution: {integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.62.2': - resolution: {integrity: sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.62.2': - resolution: {integrity: sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.62.2': - resolution: {integrity: sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.62.2': - resolution: {integrity: sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.62.2': - resolution: {integrity: sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==} - cpu: [x64] - os: [win32] - - '@sindresorhus/is@7.2.0': - resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} - engines: {node: '>=18'} - - '@speed-highlight/core@1.2.17': - resolution: {integrity: sha512-Z92FwKpCtfaW1V0jTU/fh3QzYEZN8wDwrzRIBoADCJfn4mJCNcJN/XegifX7BDrQ8/h9Xh/JnbyMchL0FqXrkg==} - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@tokenizer/inflate@0.4.1': - resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} - engines: {node: '>=18'} - - '@tokenizer/token@0.3.0': - resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - - '@tybys/wasm-util@0.10.3': - resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} - - '@types/debug@4.1.13': - resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} - - '@types/estree@1.0.9': - resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - - '@types/gensync@1.0.5': - resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} - - '@types/jsesc@2.5.1': - resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/mdast@4.0.4': - resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - - '@types/ms@2.1.0': - resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - - '@types/unist@3.0.3': - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - - '@vercel/oidc@3.2.0': - resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} - engines: {node: '>= 20'} - - '@workflow/serde@4.1.0-beta.2': - resolution: {integrity: sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww==} - - abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} - - accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} - - acorn@8.17.0: - resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} - engines: {node: '>=0.4.0'} - hasBin: true - - agents@0.17.4: - resolution: {integrity: sha512-K6YRbpD3VcwdTOPBlDgI4dILAwkhXo5cdxTlVF0IvUwQEKfMPawmH8E/QMXTN8CPGHqVYgYFACxTyk6nKlK+vg==} - hasBin: true - peerDependencies: - '@ai-sdk/react': ^3.0.204 - '@tanstack/ai': '>=0.10.2 <1.0.0' - '@x402/core': ^2.0.0 - '@x402/evm': ^2.0.0 - ai: ^6.0.0 - chat: ^4.29.0 - just-bash: ^3.0.0 - react: ^19.0.0 - vite: '>=6.0.0 <9.0.0' - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@tanstack/ai': - optional: true - '@x402/core': - optional: true - '@x402/evm': - optional: true - ai: - optional: true - chat: - optional: true - just-bash: - optional: true - vite: - optional: true - - ai@6.0.202: - resolution: {integrity: sha512-14O7uyHVa5lXyt1RzduRqM1zwOnLBN+EaE+btWiP2R7GLHd5oh+Z9uaebR785V/Y2hXlxvuQGsw2Gj6iHpkxsg==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - ajv-formats@3.0.1: - resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - - ajv@8.20.0: - resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} - - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} - engines: {node: '>=12'} - - ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} - engines: {node: '>=12'} - - anynum@1.0.1: - resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==} - - async-lock@1.4.1: - resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} - - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - - aywson@0.0.16: - resolution: {integrity: sha512-xLFICM6OgSMcysNHCgrhri7hpcn0TfuyU5KxtjpIAJAUuD0Bjph2pSkLgxjn45iQBjBxs4S5Fq+RmXhIYuQtNw==} - hasBin: true - - bail@2.0.2: - resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - - balanced-match@4.0.4: - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} - engines: {node: 18 || 20 || >=22} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - baseline-browser-mapping@2.10.43: - resolution: {integrity: sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==} - engines: {node: '>=6.0.0'} - hasBin: true - - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - - blake3-wasm@2.1.5: - resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} - - body-parser@2.3.0: - resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} - engines: {node: '>=18'} - - brace-expansion@5.0.12: - resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} - engines: {node: 20 || >=22} - - browserslist@4.28.6: - resolution: {integrity: sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.9: - resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - caniuse-lite@1.0.30001806: - resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==} - - ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - - chalk@5.6.2: - resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - character-entities@2.0.2: - resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} - - chat@4.34.0: - resolution: {integrity: sha512-g3c9ANavtCX7BwHcB5c3lWKIUm+8Oo7qlbgQ7/ni1rmVLLeCQa7FiMfeIyEyTAd/4HlRQu5jcS4EPdb0VyhUDQ==} - engines: {node: '>=20'} - peerDependencies: - ai: ^6.0.182 || ^7.0.0 - zod: ^3.0.0 || ^4.0.0 - peerDependenciesMeta: - ai: - optional: true - zod: - optional: true - - chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - - clean-git-ref@2.0.1: - resolution: {integrity: sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==} - - cliui@9.0.1: - resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} - engines: {node: '>=20'} - - commander@6.2.1: - resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} - engines: {node: '>= 6'} - - content-disposition@1.1.0: - resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} - engines: {node: '>=18'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - - content-type@2.0.0: - resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} - engines: {node: '>=18'} - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} - - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - - cookie@1.1.1: - resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} - engines: {node: '>=18'} - - core-js-pure@3.49.0: - resolution: {integrity: sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==} - - cors@2.8.6: - resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} - engines: {node: '>= 0.10'} - - crc-32@1.2.2: - resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} - engines: {node: '>=0.8'} - hasBin: true - - create-think@0.1.1: - resolution: {integrity: sha512-C8+k9fPArd1B0nnDUV83Fjw7hzJyaY+LN4v3Va+k4enMlSw0ZvyJERjJwntcp+1Snos+sy07SQYpV+1k10zARQ==} - hasBin: true - - cron-schedule@6.0.0: - resolution: {integrity: sha512-BoZaseYGXOo5j5HUwTaegIog3JJbuH4BbrY9A1ArLjXpy+RWb3mV28F/9Gv1dDA7E2L8kngWva4NWisnLTyfgQ==} - engines: {node: '>=20'} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - dc-browser@1.0.4: - resolution: {integrity: sha512-7oEtnzNlcE+hr4OvO3GR6Gndgw8BhW+wKOEwMqSleyY7N29jbAxzyW5BaJl7qBCw+6OIxfMWtY0T+6dxq8RWLw==} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decode-named-character-reference@1.3.0: - resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} - - decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} - - deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - - devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - - diff3@0.0.3: - resolution: {integrity: sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==} - - diff@8.0.4: - resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} - engines: {node: '>=0.3.1'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - electron-to-chromium@1.5.393: - resolution: {integrity: sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg==} - - emoji-regex@10.6.0: - resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} - - empathic@2.0.1: - resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} - engines: {node: '>=14'} - - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - - error-stack-parser-es@1.0.5: - resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-object-atoms@1.1.2: - resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} - engines: {node: '>= 0.4'} - - esbuild@0.28.1: - resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - event-target-polyfill@0.0.4: - resolution: {integrity: sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ==} - - event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - - events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - - eventsource-parser@3.1.0: - resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==} - engines: {node: '>=18.0.0'} - - eventsource@3.0.7: - resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} - engines: {node: '>=18.0.0'} - - expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} - - express-rate-limit@8.6.0: - resolution: {integrity: sha512-XKJXDsASUOo0LLtFwW5hCcQGH0N4WQc/Rn8/Pvoia+TJFOkkFPvrtW9lZOeeNcxQJspvOIERMwiRLsVFlhHEkA==} - engines: {node: '>= 16'} - peerDependencies: - express: '>= 4.11' - - express@5.2.1: - resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} - engines: {node: '>= 18'} - - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-uri@3.1.8: - resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} - - fast-xml-builder@1.3.0: - resolution: {integrity: sha512-F74cZEdCvuw9P41GAC3rod4X04jjWGM1JPEv/GWSqFTWLsdyMSBMBMlm9Hk3GLBgLBbdBNY8yee0pQh2RBVESQ==} - - fast-xml-parser@5.10.1: - resolution: {integrity: sha512-IEMIf7298kXuZSRFoGfMYrl7is8LpavODgbNz1cwIudv7KwVFnuU+UsMporfq6PD6aXSlawZlARiA3UywCTfMw==} - hasBin: true - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - file-type@21.3.4: - resolution: {integrity: sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==} - engines: {node: '>=20'} - - finalhandler@2.1.1: - resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} - engines: {node: '>= 18.0.0'} - - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} - - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-east-asian-width@1.6.0: - resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} - engines: {node: '>=18'} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.4: - resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} - engines: {node: '>= 0.4'} - - hono@4.13.7: - resolution: {integrity: sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ==} - engines: {node: '>=16.9.0'} - - http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} - - iconv-lite@0.7.3: - resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} - engines: {node: '>=0.10.0'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - import-meta-resolve@4.2.0: - resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - - ini@6.0.0: - resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} - engines: {node: ^20.17.0 || >=22.9.0} - - ip-address@10.7.1: - resolution: {integrity: sha512-4OUAqU9Z1i3vCnS05hzGiFnEMDpQ+62pAD/MVQOp83fYyNC8GleCqaS0QikQBmcWCrKFiUs/B8ztRRiYOAXuCA==} - engines: {node: '>= 12'} - - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - - is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} - - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} - - is-unsafe@2.0.0: - resolution: {integrity: sha512-2LdV822R+wmI86unXA93WCFpL6g+av8ynWk0nrHyJqGop5VoocYsSLFgN8jrfalT6iGeLNM4KXuVSsULP53kEA==} - - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - isomorphic-git@1.38.9: - resolution: {integrity: sha512-3nwGo1UIScJUW2/W4KzTGA/V7Bf/AivBF4KuZGfxU+Bcz2oJo2emuxJK8hP2saZ3XfLOBqbKs+x9CLsFrn8vAg==} - engines: {node: '>=14.17'} - hasBin: true - - jose@6.2.3: - resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==} - - js-base64@3.9.1: - resolution: {integrity: sha512-U73qptcvf/HIOauFOmqT3a0mDUp0MYlfd15oqoe9kqZt5XhiXVb+HG09sLvI9PQ9tZIBFS4nlErai8zbWazP0g==} - - js-tokens@10.0.0: - resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - - json-schema-typed@8.0.2: - resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} - - json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - - just-bash@3.1.0: - resolution: {integrity: sha512-/t28X8EH3+j/zvELGkNhlFV2g6hc3oHBzy6zPBnNq2nqUN0DGS9PsD889JfQ7F6ll08gqFoutiS+VJHK30wZpg==} - hasBin: true - - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - - longest-streak@3.1.0: - resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - - lru-cache@11.5.2: - resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} - engines: {node: 20 || >=22} - - markdown-table@3.0.4: - resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - mdast-util-find-and-replace@3.0.2: - resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} - - mdast-util-from-markdown@2.0.3: - resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} - - mdast-util-gfm-autolink-literal@2.0.1: - resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} - - mdast-util-gfm-footnote@2.1.0: - resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} - - mdast-util-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} - - mdast-util-gfm-table@2.0.0: - resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} - - mdast-util-gfm-task-list-item@2.0.0: - resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} - - mdast-util-gfm@3.1.0: - resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} - - mdast-util-phrasing@4.1.0: - resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} - - mdast-util-to-markdown@2.1.2: - resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} - - mdast-util-to-string@4.0.0: - resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - - media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} - - merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} - - micromark-core-commonmark@2.0.3: - resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} - - micromark-extension-gfm-autolink-literal@2.1.0: - resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} - - micromark-extension-gfm-footnote@2.1.0: - resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} - - micromark-extension-gfm-strikethrough@2.1.0: - resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} - - micromark-extension-gfm-table@2.1.1: - resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} - - micromark-extension-gfm-tagfilter@2.0.0: - resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} - - micromark-extension-gfm-task-list-item@2.1.0: - resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} - - micromark-extension-gfm@3.0.0: - resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} - - micromark-factory-destination@2.0.1: - resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} - - micromark-factory-label@2.0.1: - resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} - - micromark-factory-space@2.0.1: - resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} - - micromark-factory-title@2.0.1: - resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} - - micromark-factory-whitespace@2.0.1: - resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} - - micromark-util-character@2.1.1: - resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} - - micromark-util-chunked@2.0.1: - resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} - - micromark-util-classify-character@2.0.1: - resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} - - micromark-util-combine-extensions@2.0.1: - resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} - - micromark-util-decode-numeric-character-reference@2.0.2: - resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} - - micromark-util-decode-string@2.0.1: - resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} - - micromark-util-encode@2.0.1: - resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} - - micromark-util-html-tag-name@2.0.1: - resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} - - micromark-util-normalize-identifier@2.0.1: - resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} - - micromark-util-resolve-all@2.0.1: - resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} - - micromark-util-sanitize-uri@2.0.1: - resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} - - micromark-util-subtokenize@2.1.0: - resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} - - micromark-util-symbol@2.0.1: - resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} - - micromark-util-types@2.0.2: - resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} - - micromark@4.0.2: - resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} - engines: {node: '>=18'} - - mimetext@3.0.28: - resolution: {integrity: sha512-eQXpbNrtxLCjUtiVbR/qR09dbPgZ2o+KR1uA7QKqGhbn8QV7HIL16mXXsobBL4/8TqoYh1us31kfz+dNfCev9g==} - - mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - - miniflare@4.20260714.0: - resolution: {integrity: sha512-MYlTCLdWCPqvrYY2uLwOjXwmglXuiHE3TGGkbOW4BwjUPa1r07E0iuHwrNDIs/sxK21r+o90Jx58AV2KeNdJZw==} - engines: {node: '>=22.0.0'} - hasBin: true - - minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} - engines: {node: 18 || 20 || >=22} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - minimisted@2.0.1: - resolution: {integrity: sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==} - - mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - - modern-tar@0.7.7: - resolution: {integrity: sha512-t9VmxaqrmANnEOBhpSDI6HD192Ge48k8vmWqQQL7hSFEqHEYwZbbsu49+aKLWZeRvFs3j1pMhXOqqF4kPlvjkQ==} - engines: {node: '>=18.0.0'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - nanoid@3.3.18: - resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - nanoid@5.1.16: - resolution: {integrity: sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==} - engines: {node: ^18 || >=20} - hasBin: true - - napi-build-utils@2.0.0: - resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} - - negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} - - node-abi@3.94.0: - resolution: {integrity: sha512-W5ZNO5KRPB5TkYmGVD9F6YqhsglXJzE6etpbmT+f6EQElhiX/UTG551cnsRGvLG3fyZEg9HwaDmNmj5nwJ4z9g==} - engines: {node: '>=10'} - - node-addon-api@8.9.0: - resolution: {integrity: sha512-ekZMeaaIzSQTSpr7X2X3iJM7lTzgnx8ahAG9pJfT/7+14mlEM8ZYQ9cgCDvSSRbReFK0oHli3WrZdCiRsgAT9Q==} - engines: {node: ^18 || ^20 || >= 21} - - node-gyp-build@4.8.4: - resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} - hasBin: true - - node-liblzma@2.2.0: - resolution: {integrity: sha512-s0KzNOWwOJJgPG6wxg6cKohnAl9Wk/oW1KrQaVzJBjQwVcUGPQCzpR46Ximygjqj/3KhOrtJXnYMp/xYAXp75g==} - engines: {node: '>=16.0.0'} - hasBin: true - - node-releases@2.0.51: - resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} - engines: {node: '>=18'} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - obug@2.1.4: - resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} - engines: {node: '>=12.20.0'} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - - papaparse@5.5.4: - resolution: {integrity: sha512-SwzWD9gl/ElwYLCI0nUja1mFJzjq2D8ziShfNBa7zCHzkOozeOGDwHWQ+tvCzEZcewecWZ5U7kUopDnG+DFYEQ==} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - partyserver@0.5.8: - resolution: {integrity: sha512-htgSwiBcBu9zIYLrsxBAOvdkjukHvncbTk0nDrJgfruvZ08rxtEN1Ab4T7j9osykP80Bq3zA2oWFd3ngc4Z9uw==} - peerDependencies: - '@cloudflare/workers-types': ^4.20260424.1 - - partysocket@1.3.0: - resolution: {integrity: sha512-1zToNyolZFK/7nuAw/K2bZrNzFqaZyRoCEkS+9vG6WSC5ikrN6qWRe96q6ImU51uptz2r+dAwSkwhJVdQi4LiA==} - peerDependencies: - react: '>=17' - peerDependenciesMeta: - react: - optional: true - - path-expression-matcher@1.6.2: - resolution: {integrity: sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==} - engines: {node: '>=14.0.0'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - - path-to-regexp@8.4.2: - resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@4.0.5: - resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} - engines: {node: '>=12'} - - pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - - pkce-challenge@5.0.1: - resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} - engines: {node: '>=16.20.0'} - - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} - - postcss@8.5.26: - resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} - engines: {node: ^10 || ^12 || >=14} - - prebuild-install@7.1.3: - resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} - engines: {node: '>=10'} - deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. - hasBin: true - - process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} - - proxy-addr@2.0.8: - resolution: {integrity: sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==} - engines: {node: '>= 0.10'} - - pump@3.0.4: - resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} - - qs@6.15.3: - resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} - engines: {node: '>=0.6'} - - quickjs-emscripten-core@0.32.0: - resolution: {integrity: sha512-QFnPfjFey8EqknSrSxe1hZrf1/8z7/6s1QzGOmKo6++02r7QRRX7ZoyNaZh7JuVjWsVW87KnQrbZqnHkOAzUyg==} - - quickjs-emscripten@0.32.0: - resolution: {integrity: sha512-So0Sqw869y/S2oE3Nuc0uT3Dhqgvsj8FSrwBdsuTosVsG8ME5/OcudU1GxsrIFdFABgy17GHnTVO9TYV/bLQcA==} - engines: {node: '>=16.0.0'} - - range-parser@1.3.0: - resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} - engines: {node: '>= 0.6'} - - raw-body@3.0.2: - resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} - engines: {node: '>= 0.10'} - - rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true - - re2js@1.3.3: - resolution: {integrity: sha512-s/I5zEAo79SUK0Qw4dpZKpiMwbQ6Gz0KU2NRr7eaO4x/p2g7Vvmn3hdeXDg8VsaUjfj/ora+e9oi27LX/C9+mw==} - - react@19.2.7: - resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} - engines: {node: '>=0.10.0'} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - readable-stream@4.7.0: - resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - remark-gfm@4.0.1: - resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} - - remark-parse@11.0.0: - resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} - - remark-stringify@11.0.0: - resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} - - remend@1.3.0: - resolution: {integrity: sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw==} - - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - - rolldown@1.2.0: - resolution: {integrity: sha512-u7tgm5l4Yw1iTqUL4EcYOAt7fFvCgQMLeidrnD4GALlC6aOznCjezYajgxeyKw27u0Q5N7fwgCzjVyPIWzwuBA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - rollup@4.62.2: - resolution: {integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - seek-bzip@2.0.0: - resolution: {integrity: sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==} - hasBin: true - - semver@7.8.5: - resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} - engines: {node: '>=10'} - hasBin: true - - send@1.2.1: - resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} - engines: {node: '>= 18'} - - serve-static@2.2.1: - resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} - engines: {node: '>= 18'} - - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - sha.js@2.4.12: - resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} - engines: {node: '>= 0.10'} - hasBin: true - - sharp@0.35.5: - resolution: {integrity: sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==} - engines: {node: '>=20.9.0'} - peerDependencies: - '@types/node': '*' - peerDependenciesMeta: - '@types/node': - optional: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - side-channel-list@1.0.1: - resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.1: - resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} - engines: {node: '>= 0.4'} - - simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - - simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - - smol-toml@1.9.0: - resolution: {integrity: sha512-hpd+HLON7HdZXqYchMM/+LaTTbdK0AU3NngIJ4KVyWbY9bfQqdL9cD+4yf6dUoU2Ap4VsU0JkQi6FxAI1B2mXQ==} - engines: {node: '>= 18'} - - source-map-js@1.2.2: - resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} - engines: {node: '>=0.10.0'} - - sprintf-js@1.1.3: - resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - - sql.js@1.14.1: - resolution: {integrity: sha512-gcj8zBWU5cFsi9WUP+4bFNXAyF1iRpA3LLyS/DP5xlrNzGmPIizUeBggKa8DbDwdqaKwUcTEnChtd2grWo/x/A==} - - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - - string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-ansi@7.2.0: - resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} - engines: {node: '>=12'} - - strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - - strnum@2.4.1: - resolution: {integrity: sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==} - - strtok3@10.3.5: - resolution: {integrity: sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==} - engines: {node: '>=18'} - - supports-color@10.2.2: - resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} - engines: {node: '>=18'} - - tar-fs@2.1.5: - resolution: {integrity: sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==} - - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - - tinyglobby@0.2.17: - resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} - engines: {node: '>=12.0.0'} - - to-buffer@1.2.2: - resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} - engines: {node: '>= 0.4'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - token-types@6.1.2: - resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} - engines: {node: '>=14.16'} - - trough@2.2.0: - resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - - turndown@7.2.4: - resolution: {integrity: sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==} - engines: {node: '>=18', npm: '>=9'} - - type-is@2.1.0: - resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} - engines: {node: '>= 18'} - - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} - - uint8array-extras@1.5.0: - resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} - engines: {node: '>=18'} - - undici@7.29.1: - resolution: {integrity: sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==} - engines: {node: '>=20.18.1'} - - unenv@2.0.0-rc.24: - resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} - - unified@11.0.5: - resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} - - unist-util-is@6.0.1: - resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} - - unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} - - unist-util-visit-parents@6.0.2: - resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} - - unist-util-visit@5.1.0: - resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - vfile-message@4.0.3: - resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} - - vfile@6.0.3: - resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - - vite@7.3.5: - resolution: {integrity: sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' - less: ^4.0.0 - lightningcss: ^1.21.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - which-typed-array@1.1.22: - resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==} - engines: {node: '>= 0.4'} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - workerd@1.20260714.1: - resolution: {integrity: sha512-oIbQzfdyl9UQUnG6XLegcSq0Mgt/7WKDbFOoqGgOWCS+/fhyGB460uKEgdAQQ9RHCO/ttcNCX/KiMIQzdoeu3Q==} - engines: {node: '>=16'} - hasBin: true - - workers-ai-provider@3.3.1: - resolution: {integrity: sha512-vArwnmiAxQQF1clsXJd9ADn1xK9YUZVxE4umaMhrdsxM2kucxP430LfaoH4rn0AfoqtnuH3bfRhW1ak0r1x/8A==} - peerDependencies: - '@ai-sdk/anthropic': ^3.0.0 - '@ai-sdk/google': ^3.0.0 - '@ai-sdk/openai': ^3.0.0 - '@ai-sdk/provider': ^3.0.0 - ai: ^6.0.0 - peerDependenciesMeta: - '@ai-sdk/anthropic': - optional: true - '@ai-sdk/google': - optional: true - '@ai-sdk/openai': - optional: true - - wrangler@4.112.0: - resolution: {integrity: sha512-5H+XUD0TySCv1LuktFHDIEOkboH2nTfQs+35L+USt3MtntjDTMVIJprLgQcL2WBjulOyjxpd1vyTiSTJVW5MjQ==} - engines: {node: '>=22.0.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^5.20260714.1 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - - wrap-ansi@9.0.2: - resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} - engines: {node: '>=18'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - ws@8.21.0: - resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - xml-naming@0.3.0: - resolution: {integrity: sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==} - engines: {node: '>=16.0.0'} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yaml@2.9.0: - resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} - engines: {node: '>= 14.6'} - hasBin: true - - yargs-parser@22.0.0: - resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} - engines: {node: ^20.19.0 || ^22.12.0 || >=23} - - yargs@18.0.0: - resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=23} - - youch-core@0.3.3: - resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} - - youch@4.1.0-beta.10: - resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} - - zod-to-json-schema@3.25.2: - resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} - peerDependencies: - zod: ^3.25.28 || ^4 - - zod@4.3.6: - resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} - - zwitch@2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - -snapshots: - - '@ai-sdk/anthropic@3.0.98(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 3.0.14 - '@ai-sdk/provider-utils': 4.0.40(zod@4.3.6) - zod: 4.3.6 - - '@ai-sdk/gateway@3.0.128(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 3.0.10 - '@ai-sdk/provider-utils': 4.0.28(zod@4.3.6) - '@vercel/oidc': 3.2.0 - zod: 4.3.6 - - '@ai-sdk/openai@3.0.80(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 3.0.13 - '@ai-sdk/provider-utils': 4.0.35(zod@4.3.6) - zod: 4.3.6 - - '@ai-sdk/provider-utils@4.0.28(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 3.0.10 - '@standard-schema/spec': 1.1.0 - eventsource-parser: 3.1.0 - zod: 4.3.6 - - '@ai-sdk/provider-utils@4.0.35(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 3.0.13 - '@standard-schema/spec': 1.1.0 - eventsource-parser: 3.1.0 - zod: 4.3.6 - - '@ai-sdk/provider-utils@4.0.40(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 3.0.14 - '@standard-schema/spec': 1.1.0 - eventsource-parser: 3.1.0 - zod: 4.3.6 - - '@ai-sdk/provider@3.0.10': - dependencies: - json-schema: 0.4.0 - - '@ai-sdk/provider@3.0.13': - dependencies: - json-schema: 0.4.0 - - '@ai-sdk/provider@3.0.14': - dependencies: - json-schema: 0.4.0 - - '@babel/code-frame@8.0.0': - dependencies: - '@babel/helper-validator-identifier': 8.0.4 - js-tokens: 10.0.0 - - '@babel/compat-data@8.0.0': {} - - '@babel/core@8.0.1': - dependencies: - '@babel/code-frame': 8.0.0 - '@babel/generator': 8.0.0 - '@babel/helper-compilation-targets': 8.0.0 - '@babel/helpers': 8.0.0 - '@babel/parser': 8.0.4 - '@babel/template': 8.0.0 - '@babel/traverse': 8.0.4 - '@babel/types': 8.0.4 - '@types/gensync': 1.0.5 - convert-source-map: 2.0.0 - empathic: 2.0.1 - gensync: 1.0.0-beta.2 - import-meta-resolve: 4.2.0 - json5: 2.2.3 - obug: 2.1.4 - semver: 7.8.5 - - '@babel/generator@8.0.0': - dependencies: - '@babel/parser': 8.0.4 - '@babel/types': 8.0.4 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - '@types/jsesc': 2.5.1 - jsesc: 3.1.0 - - '@babel/helper-annotate-as-pure@8.0.0': - dependencies: - '@babel/types': 8.0.4 - - '@babel/helper-compilation-targets@8.0.0': - dependencies: - '@babel/compat-data': 8.0.0 - '@babel/helper-validator-option': 8.0.0 - browserslist: 4.28.6 - lru-cache: 11.5.2 - semver: 7.8.5 - - '@babel/helper-create-class-features-plugin@8.0.1(@babel/core@8.0.1)': - dependencies: - '@babel/core': 8.0.1 - '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-member-expression-to-functions': 8.0.0 - '@babel/helper-optimise-call-expression': 8.0.0 - '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.1) - '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 - '@babel/traverse': 8.0.4 - semver: 7.8.5 - - '@babel/helper-globals@8.0.0': {} - - '@babel/helper-member-expression-to-functions@8.0.0': - dependencies: - '@babel/traverse': 8.0.4 - '@babel/types': 8.0.4 - - '@babel/helper-optimise-call-expression@8.0.0': - dependencies: - '@babel/types': 8.0.4 - - '@babel/helper-plugin-utils@8.0.1(@babel/core@8.0.1)': - dependencies: - '@babel/core': 8.0.1 - - '@babel/helper-replace-supers@8.0.1(@babel/core@8.0.1)': - dependencies: - '@babel/core': 8.0.1 - '@babel/helper-member-expression-to-functions': 8.0.0 - '@babel/helper-optimise-call-expression': 8.0.0 - '@babel/traverse': 8.0.4 - - '@babel/helper-skip-transparent-expression-wrappers@8.0.0': - dependencies: - '@babel/traverse': 8.0.4 - '@babel/types': 8.0.4 - - '@babel/helper-string-parser@8.0.0': {} - - '@babel/helper-validator-identifier@8.0.4': {} - - '@babel/helper-validator-option@8.0.0': {} - - '@babel/helpers@8.0.0': - dependencies: - '@babel/template': 8.0.0 - '@babel/types': 8.0.4 - - '@babel/parser@8.0.4': - dependencies: - '@babel/types': 8.0.4 - - '@babel/plugin-proposal-decorators@8.0.2(@babel/core@8.0.1)': - dependencies: - '@babel/core': 8.0.1 - '@babel/helper-create-class-features-plugin': 8.0.1(@babel/core@8.0.1) - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.1) - '@babel/plugin-syntax-decorators': 8.0.1(@babel/core@8.0.1) - - '@babel/plugin-syntax-decorators@8.0.1(@babel/core@8.0.1)': - dependencies: - '@babel/core': 8.0.1 - '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.1) - - '@babel/runtime-corejs3@7.29.7': - dependencies: - core-js-pure: 3.49.0 - - '@babel/runtime@7.29.7': {} - - '@babel/template@8.0.0': - dependencies: - '@babel/code-frame': 8.0.0 - '@babel/parser': 8.0.4 - '@babel/types': 8.0.4 - - '@babel/traverse@8.0.4': - dependencies: - '@babel/code-frame': 8.0.0 - '@babel/generator': 8.0.0 - '@babel/helper-globals': 8.0.0 - '@babel/parser': 8.0.4 - '@babel/template': 8.0.0 - '@babel/types': 8.0.4 - obug: 2.1.4 - - '@babel/types@8.0.4': - dependencies: - '@babel/helper-string-parser': 8.0.0 - '@babel/helper-validator-identifier': 8.0.4 - - '@borewit/text-codec@0.2.2': {} - - '@cfworker/json-schema@4.1.1': {} - - '@cloudflare/codemode@0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6)': - dependencies: - '@types/json-schema': 7.0.15 - acorn: 8.17.0 - optionalDependencies: - '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) - ai: 6.0.202(zod@4.3.6) - zod: 4.3.6 - - '@cloudflare/kv-asset-handler@0.5.0': {} - - '@cloudflare/shell@0.4.1(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6)': - dependencies: - '@cloudflare/codemode': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - isomorphic-git: 1.38.9 - transitivePeerDependencies: - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - ai - - zod - - '@cloudflare/think@0.13.0(@ai-sdk/provider@3.0.14)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.17.4(@babel/core@8.0.1)(@babel/runtime@7.29.7)(ai@6.0.202(zod@4.3.6))(chat@4.34.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.1.0)(react@19.2.7)(rolldown@1.2.0)(vite@7.3.5(yaml@2.9.0))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.2.7)(vite@7.3.5(yaml@2.9.0))(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 3.0.98(zod@4.3.6) - '@ai-sdk/openai': 3.0.80(zod@4.3.6) - '@cloudflare/codemode': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.1(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - agents: 0.17.4(@babel/core@8.0.1)(@babel/runtime@7.29.7)(ai@6.0.202(zod@4.3.6))(chat@4.34.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.1.0)(react@19.2.7)(rolldown@1.2.0)(vite@7.3.5(yaml@2.9.0))(zod@4.3.6) - ai: 6.0.202(zod@4.3.6) - aywson: 0.0.16 - chat: 4.34.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - create-think: 0.1.1 - just-bash: 3.1.0 - smol-toml: 1.9.0 - workers-ai-provider: 3.3.1(@ai-sdk/anthropic@3.0.98(zod@4.3.6))(@ai-sdk/openai@3.0.80(zod@4.3.6))(@ai-sdk/provider@3.0.14)(ai@6.0.202(zod@4.3.6)) - yargs: 18.0.0 - zod: 4.3.6 - optionalDependencies: - react: 19.2.7 - vite: 7.3.5(yaml@2.9.0) - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - '@cloudflare/unenv-preset@2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260714.1)': - dependencies: - unenv: 2.0.0-rc.24 - optionalDependencies: - workerd: 1.20260714.1 - - '@cloudflare/vite-plugin@1.45.1(vite@7.3.5(yaml@2.9.0))(wrangler@4.112.0)': - dependencies: - '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260714.1) - miniflare: 4.20260714.0 - unenv: 2.0.0-rc.24 - vite: 7.3.5(yaml@2.9.0) - workerd: 1.20260714.1 - wrangler: 4.112.0 - ws: 8.21.0 - transitivePeerDependencies: - - '@types/node' - - bufferutil - - utf-8-validate - - '@cloudflare/workerd-darwin-64@1.20260714.1': - optional: true - - '@cloudflare/workerd-darwin-arm64@1.20260714.1': - optional: true - - '@cloudflare/workerd-linux-64@1.20260714.1': - optional: true - - '@cloudflare/workerd-linux-arm64@1.20260714.1': - optional: true - - '@cloudflare/workerd-windows-64@1.20260714.1': - optional: true - - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - - '@emnapi/core@1.11.2': - dependencies: - '@emnapi/wasi-threads': 1.2.2 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.11.2': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.11.3': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.2.2': - dependencies: - tslib: 2.8.1 - optional: true - - '@esbuild/aix-ppc64@0.28.1': - optional: true - - '@esbuild/android-arm64@0.28.1': - optional: true - - '@esbuild/android-arm@0.28.1': - optional: true - - '@esbuild/android-x64@0.28.1': - optional: true - - '@esbuild/darwin-arm64@0.28.1': - optional: true - - '@esbuild/darwin-x64@0.28.1': - optional: true - - '@esbuild/freebsd-arm64@0.28.1': - optional: true - - '@esbuild/freebsd-x64@0.28.1': - optional: true - - '@esbuild/linux-arm64@0.28.1': - optional: true - - '@esbuild/linux-arm@0.28.1': - optional: true - - '@esbuild/linux-ia32@0.28.1': - optional: true - - '@esbuild/linux-loong64@0.28.1': - optional: true - - '@esbuild/linux-mips64el@0.28.1': - optional: true - - '@esbuild/linux-ppc64@0.28.1': - optional: true - - '@esbuild/linux-riscv64@0.28.1': - optional: true - - '@esbuild/linux-s390x@0.28.1': - optional: true - - '@esbuild/linux-x64@0.28.1': - optional: true - - '@esbuild/netbsd-arm64@0.28.1': - optional: true - - '@esbuild/netbsd-x64@0.28.1': - optional: true - - '@esbuild/openbsd-arm64@0.28.1': - optional: true - - '@esbuild/openbsd-x64@0.28.1': - optional: true - - '@esbuild/openharmony-arm64@0.28.1': - optional: true - - '@esbuild/sunos-x64@0.28.1': - optional: true - - '@esbuild/win32-arm64@0.28.1': - optional: true - - '@esbuild/win32-ia32@0.28.1': - optional: true - - '@esbuild/win32-x64@0.28.1': - optional: true - - '@hono/node-server@2.1.0(hono@4.13.7)': - dependencies: - hono: 4.13.7 - - '@img/colour@1.1.0': {} - - '@img/sharp-darwin-arm64@0.35.5': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.3.4 - optional: true - - '@img/sharp-darwin-x64@0.35.5': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.3.4 - optional: true - - '@img/sharp-freebsd-wasm32@0.35.5': - dependencies: - '@img/sharp-wasm32': 0.35.5 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.3.4': - optional: true - - '@img/sharp-libvips-darwin-x64@1.3.4': - optional: true - - '@img/sharp-libvips-linux-arm64@1.3.4': - optional: true - - '@img/sharp-libvips-linux-arm@1.3.4': - optional: true - - '@img/sharp-libvips-linux-ppc64@1.3.4': - optional: true - - '@img/sharp-libvips-linux-riscv64@1.3.4': - optional: true - - '@img/sharp-libvips-linux-s390x@1.3.4': - optional: true - - '@img/sharp-libvips-linux-x64@1.3.4': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.3.4': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.3.4': - optional: true - - '@img/sharp-linux-arm64@0.35.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.3.4 - optional: true - - '@img/sharp-linux-arm@0.35.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.3.4 - optional: true - - '@img/sharp-linux-ppc64@0.35.5': - optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.3.4 - optional: true - - '@img/sharp-linux-riscv64@0.35.5': - optionalDependencies: - '@img/sharp-libvips-linux-riscv64': 1.3.4 - optional: true - - '@img/sharp-linux-s390x@0.35.5': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.3.4 - optional: true - - '@img/sharp-linux-x64@0.35.5': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.3.4 - optional: true - - '@img/sharp-linuxmusl-arm64@0.35.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.3.4 - optional: true - - '@img/sharp-linuxmusl-x64@0.35.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.3.4 - optional: true - - '@img/sharp-wasm32@0.35.5': - dependencies: - '@emnapi/runtime': 1.11.3 - optional: true - - '@img/sharp-webcontainers-wasm32@0.35.5': - dependencies: - '@img/sharp-wasm32': 0.35.5 - optional: true - - '@img/sharp-win32-arm64@0.35.5': - optional: true - - '@img/sharp-win32-ia32@0.35.5': - optional: true - - '@img/sharp-win32-x64@0.35.5': - optional: true - - '@jitl/quickjs-ffi-types@0.32.0': {} - - '@jitl/quickjs-wasmfile-debug-asyncify@0.32.0': - dependencies: - '@jitl/quickjs-ffi-types': 0.32.0 - - '@jitl/quickjs-wasmfile-debug-sync@0.32.0': - dependencies: - '@jitl/quickjs-ffi-types': 0.32.0 - - '@jitl/quickjs-wasmfile-release-asyncify@0.32.0': - dependencies: - '@jitl/quickjs-ffi-types': 0.32.0 - - '@jitl/quickjs-wasmfile-release-sync@0.32.0': - dependencies: - '@jitl/quickjs-ffi-types': 0.32.0 - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@mixmark-io/domino@2.2.0': {} - - '@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6)': - dependencies: - '@hono/node-server': 2.1.0(hono@4.13.7) - ajv: 8.20.0 - ajv-formats: 3.0.1(ajv@8.20.0) - content-type: 1.0.5 - cors: 2.8.6 - cross-spawn: 7.0.6 - eventsource: 3.0.7 - eventsource-parser: 3.1.0 - express: 5.2.1 - express-rate-limit: 8.6.0(express@5.2.1) - hono: 4.13.7 - jose: 6.2.3 - json-schema-typed: 8.0.2 - pkce-challenge: 5.0.1 - raw-body: 3.0.2 - zod: 4.3.6 - zod-to-json-schema: 3.25.2(zod@4.3.6) - optionalDependencies: - '@cfworker/json-schema': 4.1.1 - transitivePeerDependencies: - - supports-color - - '@mongodb-js/zstd@7.0.0': - dependencies: - node-addon-api: 8.9.0 - prebuild-install: 7.1.3 - optional: true - - '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)': - dependencies: - '@emnapi/core': 1.11.2 - '@emnapi/runtime': 1.11.2 - '@tybys/wasm-util': 0.10.3 - optional: true - - '@nodable/entities@3.0.0': {} - - '@opentelemetry/api@1.9.1': {} - - '@oxc-project/types@0.140.0': {} - - '@poppinss/colors@4.1.6': - dependencies: - kleur: 4.1.5 - - '@poppinss/dumper@0.6.5': - dependencies: - '@poppinss/colors': 4.1.6 - '@sindresorhus/is': 7.2.0 - supports-color: 10.2.2 - - '@poppinss/exception@1.2.3': {} - - '@rolldown/binding-android-arm64@1.2.0': - optional: true - - '@rolldown/binding-darwin-arm64@1.2.0': - optional: true - - '@rolldown/binding-darwin-x64@1.2.0': - optional: true - - '@rolldown/binding-freebsd-x64@1.2.0': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.2.0': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.2.0': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.2.0': - optional: true - - '@rolldown/binding-linux-ppc64-gnu@1.2.0': - optional: true - - '@rolldown/binding-linux-s390x-gnu@1.2.0': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.2.0': - optional: true - - '@rolldown/binding-linux-x64-musl@1.2.0': - optional: true - - '@rolldown/binding-openharmony-arm64@1.2.0': - optional: true - - '@rolldown/binding-wasm32-wasi@1.2.0': - dependencies: - '@emnapi/core': 1.11.2 - '@emnapi/runtime': 1.11.2 - '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.2.0': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.2.0': - optional: true - - '@rolldown/plugin-babel@0.2.3(@babel/core@8.0.1)(@babel/runtime@7.29.7)(rolldown@1.2.0)(vite@7.3.5(yaml@2.9.0))': - dependencies: - '@babel/core': 8.0.1 - picomatch: 4.0.5 - rolldown: 1.2.0 - optionalDependencies: - '@babel/runtime': 7.29.7 - vite: 7.3.5(yaml@2.9.0) - - '@rolldown/pluginutils@1.0.1': {} - - '@rollup/rollup-android-arm-eabi@4.62.2': - optional: true - - '@rollup/rollup-android-arm64@4.62.2': - optional: true - - '@rollup/rollup-darwin-arm64@4.62.2': - optional: true - - '@rollup/rollup-darwin-x64@4.62.2': - optional: true - - '@rollup/rollup-freebsd-arm64@4.62.2': - optional: true - - '@rollup/rollup-freebsd-x64@4.62.2': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.62.2': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.62.2': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.62.2': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.62.2': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.62.2': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.62.2': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.62.2': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.62.2': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.62.2': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.62.2': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.62.2': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.62.2': - optional: true - - '@rollup/rollup-linux-x64-musl@4.62.2': - optional: true - - '@rollup/rollup-openbsd-x64@4.62.2': - optional: true - - '@rollup/rollup-openharmony-arm64@4.62.2': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.62.2': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.62.2': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.62.2': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.62.2': - optional: true - - '@sindresorhus/is@7.2.0': {} - - '@speed-highlight/core@1.2.17': {} - - '@standard-schema/spec@1.1.0': {} - - '@tokenizer/inflate@0.4.1': - dependencies: - debug: 4.4.3 - token-types: 6.1.2 - transitivePeerDependencies: - - supports-color - - '@tokenizer/token@0.3.0': {} - - '@tybys/wasm-util@0.10.3': - dependencies: - tslib: 2.8.1 - optional: true - - '@types/debug@4.1.13': - dependencies: - '@types/ms': 2.1.0 - - '@types/estree@1.0.9': {} - - '@types/gensync@1.0.5': {} - - '@types/jsesc@2.5.1': {} - - '@types/json-schema@7.0.15': {} - - '@types/mdast@4.0.4': - dependencies: - '@types/unist': 3.0.3 - - '@types/ms@2.1.0': {} - - '@types/unist@3.0.3': {} - - '@vercel/oidc@3.2.0': {} - - '@workflow/serde@4.1.0-beta.2': {} - - abort-controller@3.0.0: - dependencies: - event-target-shim: 5.0.1 - - accepts@2.0.0: - dependencies: - mime-types: 3.0.2 - negotiator: 1.0.0 - - acorn@8.17.0: {} - - agents@0.17.4(@babel/core@8.0.1)(@babel/runtime@7.29.7)(ai@6.0.202(zod@4.3.6))(chat@4.34.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.1.0)(react@19.2.7)(rolldown@1.2.0)(vite@7.3.5(yaml@2.9.0))(zod@4.3.6): - dependencies: - '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.1) - '@cfworker/json-schema': 4.1.1 - '@cloudflare/codemode': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) - '@rolldown/plugin-babel': 0.2.3(@babel/core@8.0.1)(@babel/runtime@7.29.7)(rolldown@1.2.0)(vite@7.3.5(yaml@2.9.0)) - cron-schedule: 6.0.0 - esbuild: 0.28.1 - mimetext: 3.0.28 - nanoid: 5.1.16 - partyserver: 0.5.8 - partysocket: 1.3.0(react@19.2.7) - react: 19.2.7 - yaml: 2.9.0 - yargs: 18.0.0 - zod: 4.3.6 - optionalDependencies: - ai: 6.0.202(zod@4.3.6) - chat: 4.34.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - just-bash: 3.1.0 - vite: 7.3.5(yaml@2.9.0) - transitivePeerDependencies: - - '@babel/core' - - '@babel/plugin-transform-runtime' - - '@babel/runtime' - - '@cloudflare/workers-types' - - rolldown - - supports-color - - ai@6.0.202(zod@4.3.6): - dependencies: - '@ai-sdk/gateway': 3.0.128(zod@4.3.6) - '@ai-sdk/provider': 3.0.10 - '@ai-sdk/provider-utils': 4.0.28(zod@4.3.6) - '@opentelemetry/api': 1.9.1 - zod: 4.3.6 - - ajv-formats@3.0.1(ajv@8.20.0): - optionalDependencies: - ajv: 8.20.0 - - ajv@8.20.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.8 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - - ansi-regex@6.2.2: {} - - ansi-styles@6.2.3: {} - - anynum@1.0.1: {} - - async-lock@1.4.1: {} - - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.1.0 - - aywson@0.0.16: - dependencies: - chalk: 5.6.2 - jsonc-parser: 3.3.1 - - bail@2.0.2: {} - - balanced-match@4.0.4: {} - - base64-js@1.5.1: {} - - baseline-browser-mapping@2.10.43: {} - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - optional: true - - blake3-wasm@2.1.5: {} - - body-parser@2.3.0: - dependencies: - bytes: 3.1.2 - content-type: 2.0.0 - debug: 4.4.3 - http-errors: 2.0.1 - iconv-lite: 0.7.3 - on-finished: 2.4.1 - qs: 6.15.3 - raw-body: 3.0.2 - type-is: 2.1.0 - transitivePeerDependencies: - - supports-color - - brace-expansion@5.0.12: - dependencies: - balanced-match: 4.0.4 - - browserslist@4.28.6: - dependencies: - baseline-browser-mapping: 2.10.43 - caniuse-lite: 1.0.30001806 - electron-to-chromium: 1.5.393 - node-releases: 2.0.51 - update-browserslist-db: 1.2.3(browserslist@4.28.6) - - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - optional: true - - buffer@6.0.3: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - bytes@3.1.2: {} - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.9: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - caniuse-lite@1.0.30001806: {} - - ccount@2.0.1: {} - - chalk@5.6.2: {} - - character-entities@2.0.2: {} - - chat@4.34.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6): - dependencies: - '@workflow/serde': 4.1.0-beta.2 - mdast-util-to-string: 4.0.0 - remark-gfm: 4.0.1 - remark-parse: 11.0.0 - remark-stringify: 11.0.0 - remend: 1.3.0 - unified: 11.0.5 - optionalDependencies: - ai: 6.0.202(zod@4.3.6) - zod: 4.3.6 - transitivePeerDependencies: - - supports-color - - chownr@1.1.4: - optional: true - - clean-git-ref@2.0.1: {} - - cliui@9.0.1: - dependencies: - string-width: 7.2.0 - strip-ansi: 7.2.0 - wrap-ansi: 9.0.2 - - commander@6.2.1: {} - - content-disposition@1.1.0: {} - - content-type@1.0.5: {} - - content-type@2.0.0: {} - - convert-source-map@2.0.0: {} - - cookie-signature@1.2.2: {} - - cookie@0.7.2: {} - - cookie@1.1.1: {} - - core-js-pure@3.49.0: {} - - cors@2.8.6: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - - crc-32@1.2.2: {} - - create-think@0.1.1: {} - - cron-schedule@6.0.0: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - dc-browser@1.0.4: {} - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - decode-named-character-reference@1.3.0: - dependencies: - character-entities: 2.0.2 - - decompress-response@6.0.0: - dependencies: - mimic-response: 3.1.0 - - deep-extend@0.6.0: - optional: true - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - depd@2.0.0: {} - - dequal@2.0.3: {} - - detect-libc@2.1.2: {} - - devlop@1.1.0: - dependencies: - dequal: 2.0.3 - - diff3@0.0.3: {} - - diff@8.0.4: {} - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - ee-first@1.1.1: {} - - electron-to-chromium@1.5.393: {} - - emoji-regex@10.6.0: {} - - empathic@2.0.1: {} - - encodeurl@2.0.0: {} - - end-of-stream@1.4.5: - dependencies: - once: 1.4.0 - optional: true - - error-stack-parser-es@1.0.5: {} - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-object-atoms@1.1.2: - dependencies: - es-errors: 1.3.0 - - esbuild@0.28.1: - optionalDependencies: - '@esbuild/aix-ppc64': 0.28.1 - '@esbuild/android-arm': 0.28.1 - '@esbuild/android-arm64': 0.28.1 - '@esbuild/android-x64': 0.28.1 - '@esbuild/darwin-arm64': 0.28.1 - '@esbuild/darwin-x64': 0.28.1 - '@esbuild/freebsd-arm64': 0.28.1 - '@esbuild/freebsd-x64': 0.28.1 - '@esbuild/linux-arm': 0.28.1 - '@esbuild/linux-arm64': 0.28.1 - '@esbuild/linux-ia32': 0.28.1 - '@esbuild/linux-loong64': 0.28.1 - '@esbuild/linux-mips64el': 0.28.1 - '@esbuild/linux-ppc64': 0.28.1 - '@esbuild/linux-riscv64': 0.28.1 - '@esbuild/linux-s390x': 0.28.1 - '@esbuild/linux-x64': 0.28.1 - '@esbuild/netbsd-arm64': 0.28.1 - '@esbuild/netbsd-x64': 0.28.1 - '@esbuild/openbsd-arm64': 0.28.1 - '@esbuild/openbsd-x64': 0.28.1 - '@esbuild/openharmony-arm64': 0.28.1 - '@esbuild/sunos-x64': 0.28.1 - '@esbuild/win32-arm64': 0.28.1 - '@esbuild/win32-ia32': 0.28.1 - '@esbuild/win32-x64': 0.28.1 - - escalade@3.2.0: {} - - escape-html@1.0.3: {} - - escape-string-regexp@5.0.0: {} - - etag@1.8.1: {} - - event-target-polyfill@0.0.4: {} - - event-target-shim@5.0.1: {} - - events@3.3.0: {} - - eventsource-parser@3.1.0: {} - - eventsource@3.0.7: - dependencies: - eventsource-parser: 3.1.0 - - expand-template@2.0.3: - optional: true - - express-rate-limit@8.6.0(express@5.2.1): - dependencies: - debug: 4.4.3 - express: 5.2.1 - ip-address: 10.7.1 - transitivePeerDependencies: - - supports-color - - express@5.2.1: - dependencies: - accepts: 2.0.0 - body-parser: 2.3.0 - content-disposition: 1.1.0 - content-type: 1.0.5 - cookie: 0.7.2 - cookie-signature: 1.2.2 - debug: 4.4.3 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 2.1.1 - fresh: 2.0.0 - http-errors: 2.0.1 - merge-descriptors: 2.0.0 - mime-types: 3.0.2 - on-finished: 2.4.1 - once: 1.4.0 - parseurl: 1.3.3 - proxy-addr: 2.0.8 - qs: 6.15.3 - range-parser: 1.3.0 - router: 2.2.0 - send: 1.2.1 - serve-static: 2.2.1 - statuses: 2.0.2 - type-is: 2.1.0 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - extend@3.0.2: {} - - fast-deep-equal@3.1.3: {} - - fast-uri@3.1.8: {} - - fast-xml-builder@1.3.0: - dependencies: - path-expression-matcher: 1.6.2 - xml-naming: 0.3.0 - - fast-xml-parser@5.10.1: - dependencies: - '@nodable/entities': 3.0.0 - fast-xml-builder: 1.3.0 - is-unsafe: 2.0.0 - path-expression-matcher: 1.6.2 - strnum: 2.4.1 - xml-naming: 0.3.0 - - fdir@6.5.0(picomatch@4.0.5): - optionalDependencies: - picomatch: 4.0.5 - - file-type@21.3.4: - dependencies: - '@tokenizer/inflate': 0.4.1 - strtok3: 10.3.5 - token-types: 6.1.2 - uint8array-extras: 1.5.0 - transitivePeerDependencies: - - supports-color - - finalhandler@2.1.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - for-each@0.3.5: - dependencies: - is-callable: 1.2.7 - - forwarded@0.2.0: {} - - fresh@2.0.0: {} - - fs-constants@1.0.0: - optional: true - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - gensync@1.0.0-beta.2: {} - - get-caller-file@2.0.5: {} - - get-east-asian-width@1.6.0: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.2 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.4 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.2 - - github-from-package@0.0.0: - optional: true - - gopd@1.2.0: {} - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.4: - dependencies: - function-bind: 1.1.2 - - hono@4.13.7: {} - - http-errors@2.0.1: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.2 - toidentifier: 1.0.1 - - iconv-lite@0.7.3: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.2.1: {} - - ignore@5.3.2: {} - - import-meta-resolve@4.2.0: {} - - inherits@2.0.4: {} - - ini@1.3.8: - optional: true - - ini@6.0.0: {} - - ip-address@10.7.1: {} - - ipaddr.js@1.9.1: {} - - is-callable@1.2.7: {} - - is-plain-obj@4.1.0: {} - - is-promise@4.0.0: {} - - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.22 - - is-unsafe@2.0.0: {} - - isarray@2.0.5: {} - - isexe@2.0.0: {} - - isomorphic-git@1.38.9: - dependencies: - async-lock: 1.4.1 - clean-git-ref: 2.0.1 - crc-32: 1.2.2 - diff3: 0.0.3 - ignore: 5.3.2 - minimisted: 2.0.1 - pako: 1.0.11 - pify: 4.0.1 - readable-stream: 4.7.0 - sha.js: 2.4.12 - simple-get: 4.0.1 - - jose@6.2.3: {} - - js-base64@3.9.1: {} - - js-tokens@10.0.0: {} - - jsesc@3.1.0: {} - - json-schema-traverse@1.0.0: {} - - json-schema-typed@8.0.2: {} - - json-schema@0.4.0: {} - - json5@2.2.3: {} - - jsonc-parser@3.3.1: {} - - just-bash@3.1.0: - dependencies: - diff: 8.0.4 - fast-xml-parser: 5.10.1 - file-type: 21.3.4 - ini: 6.0.0 - minimatch: 10.2.5 - modern-tar: 0.7.7 - papaparse: 5.5.4 - quickjs-emscripten: 0.32.0 - re2js: 1.3.3 - seek-bzip: 2.0.0 - smol-toml: 1.9.0 - sprintf-js: 1.1.3 - sql.js: 1.14.1 - turndown: 7.2.4 - yaml: 2.9.0 - optionalDependencies: - '@mongodb-js/zstd': 7.0.0 - node-liblzma: 2.2.0 - transitivePeerDependencies: - - supports-color - - kleur@4.1.5: {} - - longest-streak@3.1.0: {} - - lru-cache@11.5.2: {} - - markdown-table@3.0.4: {} - - math-intrinsics@1.1.0: {} - - mdast-util-find-and-replace@3.0.2: - dependencies: - '@types/mdast': 4.0.4 - escape-string-regexp: 5.0.0 - unist-util-is: 6.0.1 - unist-util-visit-parents: 6.0.2 - - mdast-util-from-markdown@2.0.3: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - decode-named-character-reference: 1.3.0 - devlop: 1.1.0 - mdast-util-to-string: 4.0.0 - micromark: 4.0.2 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-decode-string: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - unist-util-stringify-position: 4.0.0 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-autolink-literal@2.0.1: - dependencies: - '@types/mdast': 4.0.4 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-find-and-replace: 3.0.2 - micromark-util-character: 2.1.1 - - mdast-util-gfm-footnote@2.1.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.3 - mdast-util-to-markdown: 2.1.2 - micromark-util-normalize-identifier: 2.0.1 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-strikethrough@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.3 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-table@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - markdown-table: 3.0.4 - mdast-util-from-markdown: 2.0.3 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm-task-list-item@2.0.0: - dependencies: - '@types/mdast': 4.0.4 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.3 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-gfm@3.1.0: - dependencies: - mdast-util-from-markdown: 2.0.3 - mdast-util-gfm-autolink-literal: 2.0.1 - mdast-util-gfm-footnote: 2.1.0 - mdast-util-gfm-strikethrough: 2.0.0 - mdast-util-gfm-table: 2.0.0 - mdast-util-gfm-task-list-item: 2.0.0 - mdast-util-to-markdown: 2.1.2 - transitivePeerDependencies: - - supports-color - - mdast-util-phrasing@4.1.0: - dependencies: - '@types/mdast': 4.0.4 - unist-util-is: 6.0.1 - - mdast-util-to-markdown@2.1.2: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - longest-streak: 3.1.0 - mdast-util-phrasing: 4.1.0 - mdast-util-to-string: 4.0.0 - micromark-util-classify-character: 2.0.1 - micromark-util-decode-string: 2.0.1 - unist-util-visit: 5.1.0 - zwitch: 2.0.4 - - mdast-util-to-string@4.0.0: - dependencies: - '@types/mdast': 4.0.4 - - media-typer@1.1.0: {} - - merge-descriptors@2.0.0: {} - - micromark-core-commonmark@2.0.3: - dependencies: - decode-named-character-reference: 1.3.0 - devlop: 1.1.0 - micromark-factory-destination: 2.0.1 - micromark-factory-label: 2.0.1 - micromark-factory-space: 2.0.1 - micromark-factory-title: 2.0.1 - micromark-factory-whitespace: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-chunked: 2.0.1 - micromark-util-classify-character: 2.0.1 - micromark-util-html-tag-name: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-subtokenize: 2.1.0 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-autolink-literal@2.1.0: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-footnote@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-strikethrough@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-util-chunked: 2.0.1 - micromark-util-classify-character: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-table@2.1.1: - dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm-tagfilter@2.0.0: - dependencies: - micromark-util-types: 2.0.2 - - micromark-extension-gfm-task-list-item@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-extension-gfm@3.0.0: - dependencies: - micromark-extension-gfm-autolink-literal: 2.1.0 - micromark-extension-gfm-footnote: 2.1.0 - micromark-extension-gfm-strikethrough: 2.1.0 - micromark-extension-gfm-table: 2.1.1 - micromark-extension-gfm-tagfilter: 2.0.0 - micromark-extension-gfm-task-list-item: 2.1.0 - micromark-util-combine-extensions: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-destination@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-label@2.0.1: - dependencies: - devlop: 1.1.0 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-space@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-types: 2.0.2 - - micromark-factory-title@2.0.1: - dependencies: - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-factory-whitespace@2.0.1: - dependencies: - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-character@2.1.1: - dependencies: - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-chunked@2.0.1: - dependencies: - micromark-util-symbol: 2.0.1 - - micromark-util-classify-character@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-combine-extensions@2.0.1: - dependencies: - micromark-util-chunked: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-decode-numeric-character-reference@2.0.2: - dependencies: - micromark-util-symbol: 2.0.1 - - micromark-util-decode-string@2.0.1: - dependencies: - decode-named-character-reference: 1.3.0 - micromark-util-character: 2.1.1 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-symbol: 2.0.1 - - micromark-util-encode@2.0.1: {} - - micromark-util-html-tag-name@2.0.1: {} - - micromark-util-normalize-identifier@2.0.1: - dependencies: - micromark-util-symbol: 2.0.1 - - micromark-util-resolve-all@2.0.1: - dependencies: - micromark-util-types: 2.0.2 - - micromark-util-sanitize-uri@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-encode: 2.0.1 - micromark-util-symbol: 2.0.1 - - micromark-util-subtokenize@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-util-chunked: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - - micromark-util-symbol@2.0.1: {} - - micromark-util-types@2.0.2: {} - - micromark@4.0.2: - dependencies: - '@types/debug': 4.1.13 - debug: 4.4.3 - decode-named-character-reference: 1.3.0 - devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-chunked: 2.0.1 - micromark-util-combine-extensions: 2.0.1 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-encode: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-subtokenize: 2.1.0 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - transitivePeerDependencies: - - supports-color - - mime-db@1.52.0: {} - - mime-db@1.54.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mime-types@3.0.2: - dependencies: - mime-db: 1.54.0 - - mimetext@3.0.28: - dependencies: - '@babel/runtime': 7.29.7 - '@babel/runtime-corejs3': 7.29.7 - js-base64: 3.9.1 - mime-types: 2.1.35 - - mimic-response@3.1.0: {} - - miniflare@4.20260714.0: - dependencies: - '@cspotcode/source-map-support': 0.8.1 - sharp: 0.35.5 - undici: 7.29.1 - workerd: 1.20260714.1 - ws: 8.21.0 - youch: 4.1.0-beta.10 - transitivePeerDependencies: - - '@types/node' - - bufferutil - - utf-8-validate - - minimatch@10.2.5: - dependencies: - brace-expansion: 5.0.12 - - minimist@1.2.8: {} - - minimisted@2.0.1: - dependencies: - minimist: 1.2.8 - - mkdirp-classic@0.5.3: - optional: true - - modern-tar@0.7.7: {} - - ms@2.1.3: {} - - nanoid@3.3.18: {} - - nanoid@5.1.16: {} - - napi-build-utils@2.0.0: - optional: true - - negotiator@1.0.0: {} - - node-abi@3.94.0: - dependencies: - semver: 7.8.5 - optional: true - - node-addon-api@8.9.0: - optional: true - - node-gyp-build@4.8.4: - optional: true - - node-liblzma@2.2.0: - dependencies: - node-addon-api: 8.9.0 - node-gyp-build: 4.8.4 - optional: true - - node-releases@2.0.51: {} - - object-assign@4.1.1: {} - - object-inspect@1.13.4: {} - - obug@2.1.4: {} - - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - pako@1.0.11: {} - - papaparse@5.5.4: {} - - parseurl@1.3.3: {} - - partyserver@0.5.8: - dependencies: - nanoid: 5.1.16 - - partysocket@1.3.0(react@19.2.7): - dependencies: - event-target-polyfill: 0.0.4 - optionalDependencies: - react: 19.2.7 - - path-expression-matcher@1.6.2: {} - - path-key@3.1.1: {} - - path-to-regexp@6.3.0: {} - - path-to-regexp@8.4.2: {} - - pathe@2.0.3: {} - - picocolors@1.1.1: {} - - picomatch@4.0.5: {} - - pify@4.0.1: {} - - pkce-challenge@5.0.1: {} - - possible-typed-array-names@1.1.0: {} - - postcss@8.5.26: - dependencies: - nanoid: 3.3.18 - picocolors: 1.1.1 - source-map-js: 1.2.2 - - prebuild-install@7.1.3: - dependencies: - detect-libc: 2.1.2 - expand-template: 2.0.3 - github-from-package: 0.0.0 - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - napi-build-utils: 2.0.0 - node-abi: 3.94.0 - pump: 3.0.4 - rc: 1.2.8 - simple-get: 4.0.1 - tar-fs: 2.1.5 - tunnel-agent: 0.6.0 - optional: true - - process@0.11.10: {} - - proxy-addr@2.0.8: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - pump@3.0.4: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - optional: true - - qs@6.15.3: - dependencies: - es-define-property: 1.0.1 - side-channel: 1.1.1 - - quickjs-emscripten-core@0.32.0: - dependencies: - '@jitl/quickjs-ffi-types': 0.32.0 - - quickjs-emscripten@0.32.0: - dependencies: - '@jitl/quickjs-wasmfile-debug-asyncify': 0.32.0 - '@jitl/quickjs-wasmfile-debug-sync': 0.32.0 - '@jitl/quickjs-wasmfile-release-asyncify': 0.32.0 - '@jitl/quickjs-wasmfile-release-sync': 0.32.0 - quickjs-emscripten-core: 0.32.0 - - range-parser@1.3.0: {} - - raw-body@3.0.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.1 - iconv-lite: 0.7.3 - unpipe: 1.0.0 - - rc@1.2.8: - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 - optional: true - - re2js@1.3.3: {} - - react@19.2.7: {} - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - optional: true - - readable-stream@4.7.0: - dependencies: - abort-controller: 3.0.0 - buffer: 6.0.3 - events: 3.3.0 - process: 0.11.10 - string_decoder: 1.3.0 - - remark-gfm@4.0.1: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-gfm: 3.1.0 - micromark-extension-gfm: 3.0.0 - remark-parse: 11.0.0 - remark-stringify: 11.0.0 - unified: 11.0.5 - transitivePeerDependencies: - - supports-color - - remark-parse@11.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-from-markdown: 2.0.3 - micromark-util-types: 2.0.2 - unified: 11.0.5 - transitivePeerDependencies: - - supports-color - - remark-stringify@11.0.0: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-to-markdown: 2.1.2 - unified: 11.0.5 - - remend@1.3.0: {} - - require-from-string@2.0.2: {} - - rolldown@1.2.0: - dependencies: - '@oxc-project/types': 0.140.0 - '@rolldown/pluginutils': 1.0.1 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.2.0 - '@rolldown/binding-darwin-arm64': 1.2.0 - '@rolldown/binding-darwin-x64': 1.2.0 - '@rolldown/binding-freebsd-x64': 1.2.0 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.0 - '@rolldown/binding-linux-arm64-gnu': 1.2.0 - '@rolldown/binding-linux-arm64-musl': 1.2.0 - '@rolldown/binding-linux-ppc64-gnu': 1.2.0 - '@rolldown/binding-linux-s390x-gnu': 1.2.0 - '@rolldown/binding-linux-x64-gnu': 1.2.0 - '@rolldown/binding-linux-x64-musl': 1.2.0 - '@rolldown/binding-openharmony-arm64': 1.2.0 - '@rolldown/binding-wasm32-wasi': 1.2.0 - '@rolldown/binding-win32-arm64-msvc': 1.2.0 - '@rolldown/binding-win32-x64-msvc': 1.2.0 - - rollup@4.62.2: - dependencies: - '@types/estree': 1.0.9 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.62.2 - '@rollup/rollup-android-arm64': 4.62.2 - '@rollup/rollup-darwin-arm64': 4.62.2 - '@rollup/rollup-darwin-x64': 4.62.2 - '@rollup/rollup-freebsd-arm64': 4.62.2 - '@rollup/rollup-freebsd-x64': 4.62.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.62.2 - '@rollup/rollup-linux-arm-musleabihf': 4.62.2 - '@rollup/rollup-linux-arm64-gnu': 4.62.2 - '@rollup/rollup-linux-arm64-musl': 4.62.2 - '@rollup/rollup-linux-loong64-gnu': 4.62.2 - '@rollup/rollup-linux-loong64-musl': 4.62.2 - '@rollup/rollup-linux-ppc64-gnu': 4.62.2 - '@rollup/rollup-linux-ppc64-musl': 4.62.2 - '@rollup/rollup-linux-riscv64-gnu': 4.62.2 - '@rollup/rollup-linux-riscv64-musl': 4.62.2 - '@rollup/rollup-linux-s390x-gnu': 4.62.2 - '@rollup/rollup-linux-x64-gnu': 4.62.2 - '@rollup/rollup-linux-x64-musl': 4.62.2 - '@rollup/rollup-openbsd-x64': 4.62.2 - '@rollup/rollup-openharmony-arm64': 4.62.2 - '@rollup/rollup-win32-arm64-msvc': 4.62.2 - '@rollup/rollup-win32-ia32-msvc': 4.62.2 - '@rollup/rollup-win32-x64-gnu': 4.62.2 - '@rollup/rollup-win32-x64-msvc': 4.62.2 - fsevents: 2.3.3 - - router@2.2.0: - dependencies: - debug: 4.4.3 - depd: 2.0.0 - is-promise: 4.0.0 - parseurl: 1.3.3 - path-to-regexp: 8.4.2 - transitivePeerDependencies: - - supports-color - - safe-buffer@5.2.1: {} - - safer-buffer@2.1.2: {} - - seek-bzip@2.0.0: - dependencies: - commander: 6.2.1 - - semver@7.8.5: {} - - send@1.2.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.1 - mime-types: 3.0.2 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.3.0 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - serve-static@2.2.1: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.2.1 - transitivePeerDependencies: - - supports-color - - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - setprototypeof@1.2.0: {} - - sha.js@2.4.12: - dependencies: - inherits: 2.0.4 - safe-buffer: 5.2.1 - to-buffer: 1.2.2 - - sharp@0.35.5: - dependencies: - '@img/colour': 1.1.0 - detect-libc: 2.1.2 - semver: 7.8.5 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.35.5 - '@img/sharp-darwin-x64': 0.35.5 - '@img/sharp-freebsd-wasm32': 0.35.5 - '@img/sharp-libvips-darwin-arm64': 1.3.4 - '@img/sharp-libvips-darwin-x64': 1.3.4 - '@img/sharp-libvips-linux-arm': 1.3.4 - '@img/sharp-libvips-linux-arm64': 1.3.4 - '@img/sharp-libvips-linux-ppc64': 1.3.4 - '@img/sharp-libvips-linux-riscv64': 1.3.4 - '@img/sharp-libvips-linux-s390x': 1.3.4 - '@img/sharp-libvips-linux-x64': 1.3.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.3.4 - '@img/sharp-libvips-linuxmusl-x64': 1.3.4 - '@img/sharp-linux-arm': 0.35.5 - '@img/sharp-linux-arm64': 0.35.5 - '@img/sharp-linux-ppc64': 0.35.5 - '@img/sharp-linux-riscv64': 0.35.5 - '@img/sharp-linux-s390x': 0.35.5 - '@img/sharp-linux-x64': 0.35.5 - '@img/sharp-linuxmusl-arm64': 0.35.5 - '@img/sharp-linuxmusl-x64': 0.35.5 - '@img/sharp-webcontainers-wasm32': 0.35.5 - '@img/sharp-win32-arm64': 0.35.5 - '@img/sharp-win32-ia32': 0.35.5 - '@img/sharp-win32-x64': 0.35.5 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - side-channel-list@1.0.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.1 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - simple-concat@1.0.1: {} - - simple-get@4.0.1: - dependencies: - decompress-response: 6.0.0 - once: 1.4.0 - simple-concat: 1.0.1 - - smol-toml@1.9.0: {} - - source-map-js@1.2.2: {} - - sprintf-js@1.1.3: {} - - sql.js@1.14.1: {} - - statuses@2.0.2: {} - - string-width@7.2.0: - dependencies: - emoji-regex: 10.6.0 - get-east-asian-width: 1.6.0 - strip-ansi: 7.2.0 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@7.2.0: - dependencies: - ansi-regex: 6.2.2 - - strip-json-comments@2.0.1: - optional: true - - strnum@2.4.1: - dependencies: - anynum: 1.0.1 - - strtok3@10.3.5: - dependencies: - '@tokenizer/token': 0.3.0 - - supports-color@10.2.2: {} - - tar-fs@2.1.5: - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.4 - tar-stream: 2.2.0 - optional: true - - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.5 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - optional: true - - tinyglobby@0.2.17: - dependencies: - fdir: 6.5.0(picomatch@4.0.5) - picomatch: 4.0.5 - - to-buffer@1.2.2: - dependencies: - isarray: 2.0.5 - safe-buffer: 5.2.1 - typed-array-buffer: 1.0.3 - - toidentifier@1.0.1: {} - - token-types@6.1.2: - dependencies: - '@borewit/text-codec': 0.2.2 - '@tokenizer/token': 0.3.0 - ieee754: 1.2.1 - - trough@2.2.0: {} - - tslib@2.8.1: - optional: true - - tunnel-agent@0.6.0: - dependencies: - safe-buffer: 5.2.1 - optional: true - - turndown@7.2.4: - dependencies: - '@mixmark-io/domino': 2.2.0 - - type-is@2.1.0: - dependencies: - content-type: 2.0.0 - media-typer: 1.1.0 - mime-types: 3.0.2 - - typed-array-buffer@1.0.3: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-typed-array: 1.1.15 - - uint8array-extras@1.5.0: {} - - undici@7.29.1: {} - - unenv@2.0.0-rc.24: - dependencies: - pathe: 2.0.3 - - unified@11.0.5: - dependencies: - '@types/unist': 3.0.3 - bail: 2.0.2 - devlop: 1.1.0 - extend: 3.0.2 - is-plain-obj: 4.1.0 - trough: 2.2.0 - vfile: 6.0.3 - - unist-util-is@6.0.1: - dependencies: - '@types/unist': 3.0.3 - - unist-util-stringify-position@4.0.0: - dependencies: - '@types/unist': 3.0.3 - - unist-util-visit-parents@6.0.2: - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.1 - - unist-util-visit@5.1.0: - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.1 - unist-util-visit-parents: 6.0.2 - - unpipe@1.0.0: {} - - update-browserslist-db@1.2.3(browserslist@4.28.6): - dependencies: - browserslist: 4.28.6 - escalade: 3.2.0 - picocolors: 1.1.1 - - util-deprecate@1.0.2: - optional: true - - vary@1.1.2: {} - - vfile-message@4.0.3: - dependencies: - '@types/unist': 3.0.3 - unist-util-stringify-position: 4.0.0 - - vfile@6.0.3: - dependencies: - '@types/unist': 3.0.3 - vfile-message: 4.0.3 - - vite@7.3.5(yaml@2.9.0): - dependencies: - esbuild: 0.28.1 - fdir: 6.5.0(picomatch@4.0.5) - picomatch: 4.0.5 - postcss: 8.5.26 - rollup: 4.62.2 - tinyglobby: 0.2.17 - optionalDependencies: - fsevents: 2.3.3 - yaml: 2.9.0 - - which-typed-array@1.1.22: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.9 - call-bound: 1.0.4 - for-each: 0.3.5 - get-proto: 1.0.1 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - workerd@1.20260714.1: - optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20260714.1 - '@cloudflare/workerd-darwin-arm64': 1.20260714.1 - '@cloudflare/workerd-linux-64': 1.20260714.1 - '@cloudflare/workerd-linux-arm64': 1.20260714.1 - '@cloudflare/workerd-windows-64': 1.20260714.1 - - workers-ai-provider@3.3.1(@ai-sdk/anthropic@3.0.98(zod@4.3.6))(@ai-sdk/openai@3.0.80(zod@4.3.6))(@ai-sdk/provider@3.0.14)(ai@6.0.202(zod@4.3.6)): - dependencies: - '@ai-sdk/provider': 3.0.14 - ai: 6.0.202(zod@4.3.6) - optionalDependencies: - '@ai-sdk/anthropic': 3.0.98(zod@4.3.6) - '@ai-sdk/openai': 3.0.80(zod@4.3.6) - - wrangler@4.112.0: - dependencies: - '@cloudflare/kv-asset-handler': 0.5.0 - '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260714.1) - blake3-wasm: 2.1.5 - esbuild: 0.28.1 - miniflare: 4.20260714.0 - path-to-regexp: 6.3.0 - unenv: 2.0.0-rc.24 - workerd: 1.20260714.1 - optionalDependencies: - fsevents: 2.3.3 - transitivePeerDependencies: - - '@types/node' - - bufferutil - - utf-8-validate - - wrap-ansi@9.0.2: - dependencies: - ansi-styles: 6.2.3 - string-width: 7.2.0 - strip-ansi: 7.2.0 - - wrappy@1.0.2: {} - - ws@8.21.0: {} - - xml-naming@0.3.0: {} - - y18n@5.0.8: {} - - yaml@2.9.0: {} - - yargs-parser@22.0.0: {} - - yargs@18.0.0: - dependencies: - cliui: 9.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - string-width: 7.2.0 - y18n: 5.0.8 - yargs-parser: 22.0.0 - - youch-core@0.3.3: - dependencies: - '@poppinss/exception': 1.2.3 - error-stack-parser-es: 1.0.5 - - youch@4.1.0-beta.10: - dependencies: - '@poppinss/colors': 4.1.6 - '@poppinss/dumper': 0.6.5 - '@speed-highlight/core': 1.2.17 - cookie: 1.1.1 - youch-core: 0.3.3 - - zod-to-json-schema@3.25.2(zod@4.3.6): - dependencies: - zod: 4.3.6 - - zod@4.3.6: {} - - zwitch@2.0.4: {} + .: {} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts b/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts index 19d3a1101..4868551cf 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts +++ b/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts @@ -1,3 +1,5 @@ +import { promises as fs } from "node:fs"; +import path from "node:path"; import { describe } from "vitest"; import { prepareScenarioDir, @@ -7,30 +9,57 @@ import { import { defineCloudflareThinkAssertions } from "./assertions"; const originalScenarioDir = resolveScenarioDir(import.meta.url); -const scenarioDir = await prepareScenarioDir({ - scenarioDir: originalScenarioDir, -}); const TIMEOUT_MS = 300_000; -const variants = await Promise.all( - [ - { - dependencyName: "cloudflare-think-v0", - label: "0.13 pinned", - variantKey: "cloudflare-think-v0", - }, - { - dependencyName: "cloudflare-think-v0-latest", - label: "0.13 latest", - variantKey: "cloudflare-think-v0-latest", - }, - ].map(async (variant) => ({ - ...variant, - version: await readInstalledPackageVersion( - scenarioDir, - variant.dependencyName, - ), - })), -); +const variants = []; + +for (const aiMajor of [6, 7]) { + const sourceDir = path.resolve( + originalScenarioDir, + `../../.bt-tmp/generated-scenarios/cloudflare-think-ai${aiMajor}`, + ); + await fs.rm(sourceDir, { recursive: true, force: true }); + await fs.mkdir(sourceDir, { recursive: true }); + await fs.cp(path.join(originalScenarioDir, "template"), sourceDir, { + recursive: true, + }); + await fs.cp( + path.join(originalScenarioDir, "versions", `ai${aiMajor}`), + sourceDir, + { recursive: true }, + ); + const minors = + aiMajor === 6 ? [13, 14, 15, 16, 17, 18, 19] : [15, 16, 17, 18, 19, 20]; + for (const minor of minors) { + for (const lane of [ + "pinned", + "latest", + ...(minor === 20 ? ["0.20.1"] : []), + ]) { + // Each concurrently running variant writes its own .dev.vars and Worker + // storage. Share the dependency cache, but not the application directory. + const scenarioDir = await prepareScenarioDir({ scenarioDir: sourceDir }); + const dependencyName = `cloudflare-think-v0-${minor}${ + lane === "latest" ? "-latest" : lane === "0.20.1" ? "-1" : "" + }`; + variants.push({ + aiMajor, + agentsPackageName: + minor === 13 + ? "agents-v0-17" + : minor === 14 || (minor === 15 && lane === "pinned") + ? "agents-v0-18" + : minor <= 17 + ? "agents-v0-22" + : "agents", + dependencyName, + label: `0.${minor} ${lane} / AI SDK ${aiMajor}`, + scenarioDir, + variantKey: `${dependencyName}-ai${aiMajor}`, + version: await readInstalledPackageVersion(scenarioDir, dependencyName), + }); + } + } +} const describeVariants = process.env.BRAINTRUST_E2E_CASSETTE_MODE === "record" || @@ -43,18 +72,20 @@ describeVariants("Cloudflare Think variants", () => { describe.sequential(`${variant.label} (${variant.version})`, () => { for (const mode of ["manual", "auto"] as const) { defineCloudflareThinkAssertions({ + usesV7Telemetry: variant.aiMajor === 7 && mode === "auto", name: `${mode} Workers/Vite instrumentation`, runScenario: async ({ runScenarioDir }) => { await runScenarioDir({ env: { CLOUDFLARE_THINK_INSTRUMENTATION: mode, CLOUDFLARE_THINK_PACKAGE_NAME: variant.dependencyName, + CLOUDFLARE_AGENTS_PACKAGE_NAME: variant.agentsPackageName, }, runContext: { originalScenarioDir, variantKey: `${variant.variantKey}-${mode}`, }, - scenarioDir, + scenarioDir: variant.scenarioDir, timeoutMs: TIMEOUT_MS, }); }, diff --git a/e2e/scenarios/cloudflare-think-instrumentation/scenario.ts b/e2e/scenarios/cloudflare-think-instrumentation/template/scenario.ts similarity index 89% rename from e2e/scenarios/cloudflare-think-instrumentation/scenario.ts rename to e2e/scenarios/cloudflare-think-instrumentation/template/scenario.ts index f581fd848..44948f358 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/scenario.ts +++ b/e2e/scenarios/cloudflare-think-instrumentation/template/scenario.ts @@ -2,6 +2,7 @@ import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process"; import { once } from "node:events"; import { writeFile } from "node:fs/promises"; import { createRequire } from "node:module"; +import { createServer, type AddressInfo } from "node:net"; import path from "node:path"; const require = createRequire(import.meta.url); @@ -9,7 +10,15 @@ const viteBin = path.join( path.dirname(require.resolve("vite/package.json")), "bin/vite.js", ); -const port = 9400 + Math.floor(Math.random() * 400); +const portReservation = createServer(); +await new Promise((resolve, reject) => { + portReservation.once("error", reject); + portReservation.listen(0, "127.0.0.1", resolve); +}); +const port = (portReservation.address() as AddressInfo).port; +await new Promise((resolve, reject) => + portReservation.close((error) => (error ? reject(error) : resolve())), +); const origin = `http://127.0.0.1:${port}`; await writeFile( ".dev.vars", diff --git a/e2e/scenarios/cloudflare-think-instrumentation/src/worker.ts b/e2e/scenarios/cloudflare-think-instrumentation/template/src/worker.ts similarity index 100% rename from e2e/scenarios/cloudflare-think-instrumentation/src/worker.ts rename to e2e/scenarios/cloudflare-think-instrumentation/template/src/worker.ts diff --git a/e2e/scenarios/cloudflare-think-instrumentation/src/wrapped-ai.ts b/e2e/scenarios/cloudflare-think-instrumentation/template/src/wrapped-ai.ts similarity index 100% rename from e2e/scenarios/cloudflare-think-instrumentation/src/wrapped-ai.ts rename to e2e/scenarios/cloudflare-think-instrumentation/template/src/wrapped-ai.ts diff --git a/e2e/scenarios/cloudflare-think-instrumentation/vite.config.ts b/e2e/scenarios/cloudflare-think-instrumentation/template/vite.config.ts similarity index 81% rename from e2e/scenarios/cloudflare-think-instrumentation/vite.config.ts rename to e2e/scenarios/cloudflare-think-instrumentation/template/vite.config.ts index 9a28d8c50..6b53df1ac 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/vite.config.ts +++ b/e2e/scenarios/cloudflare-think-instrumentation/template/vite.config.ts @@ -21,6 +21,10 @@ export default defineConfig({ resolve: { alias: { "@cloudflare/think": thinkPackageName, + ...(process.env.CLOUDFLARE_AGENTS_PACKAGE_NAME !== "agents" && + process.env.CLOUDFLARE_AGENTS_PACKAGE_NAME + ? { agents: process.env.CLOUDFLARE_AGENTS_PACKAGE_NAME } + : {}), ...(manual ? { ai: new URL("./src/wrapped-ai.ts", import.meta.url).pathname, diff --git a/e2e/scenarios/cloudflare-think-instrumentation/wrangler.jsonc b/e2e/scenarios/cloudflare-think-instrumentation/template/wrangler.jsonc similarity index 100% rename from e2e/scenarios/cloudflare-think-instrumentation/wrangler.jsonc rename to e2e/scenarios/cloudflare-think-instrumentation/template/wrangler.jsonc diff --git a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/package.json b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/package.json new file mode 100644 index 000000000..90111456b --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/package.json @@ -0,0 +1,57 @@ +{ + "name": "@braintrust/e2e-cloudflare-think-ai6", + "private": true, + "type": "module", + "dependencies": { + "@ai-sdk/openai": "3.0.80", + "@cloudflare/vite-plugin": "1.45.1", + "agents": "0.28.0", + "ai": "6.0.202", + "ai-unwrapped": "npm:ai@6.0.202", + "dc-browser": "1.0.4", + "vite": "7.3.5", + "wrangler": "4.112.0", + "zod": "4.3.6", + "cloudflare-think-v0-13": "npm:@cloudflare/think@0.13.0", + "cloudflare-think-v0-13-latest": "npm:@cloudflare/think@0.13.0", + "cloudflare-think-v0-14": "npm:@cloudflare/think@0.14.0", + "cloudflare-think-v0-14-latest": "npm:@cloudflare/think@0.14.0", + "cloudflare-think-v0-15": "npm:@cloudflare/think@0.15.0", + "cloudflare-think-v0-15-latest": "npm:@cloudflare/think@0.15.1", + "cloudflare-think-v0-16": "npm:@cloudflare/think@0.16.0", + "cloudflare-think-v0-16-latest": "npm:@cloudflare/think@0.16.0", + "cloudflare-think-v0-17": "npm:@cloudflare/think@0.17.0", + "cloudflare-think-v0-17-latest": "npm:@cloudflare/think@0.17.0", + "cloudflare-think-v0-18": "npm:@cloudflare/think@0.18.0", + "cloudflare-think-v0-18-latest": "npm:@cloudflare/think@0.18.0", + "cloudflare-think-v0-19": "npm:@cloudflare/think@0.19.0", + "cloudflare-think-v0-19-latest": "npm:@cloudflare/think@0.19.0", + "agents-v0-17": "npm:agents@0.17.4", + "agents-v0-18": "npm:agents@0.18.0", + "agents-v0-22": "npm:agents@0.22.0" + }, + "pnpm": { + "overrides": { + "esbuild@<0.28.1": "^0.28.1", + "ip-address@<10.2.2": "10.7.1", + "sharp@<0.35.0": "0.35.5", + "@hono/node-server@<2.0.5": "^2.0.10", + "brace-expansion@5.0.7": "5.0.12", + "undici@<7.29.0": "7.29.1", + "hono@<4.12.34": "4.13.7", + "nanoid@<3.3.18": "^3.3.18", + "fast-uri@<3.1.5": "3.1.8", + "postcss@<8.5.23": "^8.5.23", + "fast-uri@>=3.0.0 <3.1.8": "3.1.8", + "ip-address@>=10.0.0 <10.7.1": "10.7.1", + "undici@>=7.0.0 <7.29.1": "7.29.1", + "brace-expansion@>=5.0.0 <5.0.12": "5.0.12", + "hono@>=4.0.0 <4.13.7": "4.13.7", + "proxy-addr@>=2.0.0 <2.0.8": "2.0.8", + "source-map-js@>=1.0.0 <1.2.2": "1.2.2", + "smol-toml@>=1.0.0 <1.9.0": "1.9.0", + "sharp@>=0.35.0 <0.35.5": "0.35.5", + "@modelcontextprotocol/sdk@>=1.0.0 <1.31.0": "1.31.0" + } + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/pnpm-lock.yaml b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/pnpm-lock.yaml new file mode 100644 index 000000000..32bb627e0 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/pnpm-lock.yaml @@ -0,0 +1,5655 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + esbuild@<0.28.1: ^0.28.1 + ip-address@<10.2.2: 10.7.1 + sharp@<0.35.0: 0.35.5 + '@hono/node-server@<2.0.5': ^2.0.10 + brace-expansion@5.0.7: 5.0.12 + undici@<7.29.0: 7.29.1 + hono@<4.12.34: 4.13.7 + nanoid@<3.3.18: ^3.3.18 + fast-uri@<3.1.5: 3.1.8 + postcss@<8.5.23: ^8.5.23 + fast-uri@>=3.0.0 <3.1.8: 3.1.8 + ip-address@>=10.0.0 <10.7.1: 10.7.1 + undici@>=7.0.0 <7.29.1: 7.29.1 + brace-expansion@>=5.0.0 <5.0.12: 5.0.12 + hono@>=4.0.0 <4.13.7: 4.13.7 + proxy-addr@>=2.0.0 <2.0.8: 2.0.8 + source-map-js@>=1.0.0 <1.2.2: 1.2.2 + smol-toml@>=1.0.0 <1.9.0: 1.9.0 + sharp@>=0.35.0 <0.35.5: 0.35.5 + '@modelcontextprotocol/sdk@>=1.0.0 <1.31.0': 1.31.0 + +importers: + + .: + dependencies: + '@ai-sdk/openai': + specifier: 3.0.80 + version: 3.0.80(zod@4.3.6) + '@cloudflare/vite-plugin': + specifier: 1.45.1 + version: 1.45.1(vite@7.3.5(yaml@2.9.1))(wrangler@4.112.0(@cloudflare/workers-types@5.20261019.1)) + agents: + specifier: 0.28.0 + version: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + agents-v0-17: + specifier: npm:agents@0.17.4 + version: agents@0.17.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/workers-types@5.20261019.1)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + agents-v0-18: + specifier: npm:agents@0.18.0 + version: agents@0.18.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/workers-types@5.20261019.1)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + agents-v0-22: + specifier: npm:agents@0.22.0 + version: agents@0.22.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: + specifier: 6.0.202 + version: 6.0.202(zod@4.3.6) + ai-unwrapped: + specifier: npm:ai@6.0.202 + version: ai@6.0.202(zod@4.3.6) + cloudflare-think-v0-13: + specifier: npm:@cloudflare/think@0.13.0 + version: '@cloudflare/think@0.13.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' + cloudflare-think-v0-13-latest: + specifier: npm:@cloudflare/think@0.13.0 + version: '@cloudflare/think@0.13.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' + cloudflare-think-v0-14: + specifier: npm:@cloudflare/think@0.14.0 + version: '@cloudflare/think@0.14.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' + cloudflare-think-v0-14-latest: + specifier: npm:@cloudflare/think@0.14.0 + version: '@cloudflare/think@0.14.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' + cloudflare-think-v0-15: + specifier: npm:@cloudflare/think@0.15.0 + version: '@cloudflare/think@0.15.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' + cloudflare-think-v0-15-latest: + specifier: npm:@cloudflare/think@0.15.1 + version: '@cloudflare/think@0.15.1(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' + cloudflare-think-v0-16: + specifier: npm:@cloudflare/think@0.16.0 + version: '@cloudflare/think@0.16.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-16-latest: + specifier: npm:@cloudflare/think@0.16.0 + version: '@cloudflare/think@0.16.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-17: + specifier: npm:@cloudflare/think@0.17.0 + version: '@cloudflare/think@0.17.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-17-latest: + specifier: npm:@cloudflare/think@0.17.0 + version: '@cloudflare/think@0.17.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-18: + specifier: npm:@cloudflare/think@0.18.0 + version: '@cloudflare/think@0.18.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-18-latest: + specifier: npm:@cloudflare/think@0.18.0 + version: '@cloudflare/think@0.18.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-19: + specifier: npm:@cloudflare/think@0.19.0 + version: '@cloudflare/think@0.19.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-19-latest: + specifier: npm:@cloudflare/think@0.19.0 + version: '@cloudflare/think@0.19.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + dc-browser: + specifier: 1.0.4 + version: 1.0.4 + vite: + specifier: 7.3.5 + version: 7.3.5(yaml@2.9.1) + wrangler: + specifier: 4.112.0 + version: 4.112.0(@cloudflare/workers-types@5.20261019.1) + zod: + specifier: 4.3.6 + version: 4.3.6 + +packages: + + '@ai-sdk/anthropic@3.0.134': + resolution: {integrity: sha512-G+U+KXy+h8VZHYKRLFuIY9TQkajOZhS2SZGTDqPwgaXe76YuT/pBskib6h3zQ8GAQFavaIpOcVStygZ8acKF2w==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/anthropic@4.0.84': + resolution: {integrity: sha512-jcqib3OpVtcMmJDWYpQqkjAusaLyqfORyM4bDc3UwLgP/usfiTONfj98HeQCLwMJ2uxrmSWiXFga2Rw/k50usw==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/gateway@3.0.128': + resolution: {integrity: sha512-t9Dyqk5thSmIzsNvVTQtZZiO3xqKGkk1hX3+GNpYmro+GuEdW+E6mKFHihb9Y1vCEt3rEyd4pbGUcin4D57FfQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/openai@3.0.80': + resolution: {integrity: sha512-u3EfYbBG4YS/U2eOGH0yv8lPRwDj25X3sTluUKMYEwOLTZzWYv0IPtrpO7tPEra0QU4oq5Gpg49/FGFSrzE4vA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/openai@4.0.98': + resolution: {integrity: sha512-RvrbLblENKj//cQWlzsbmVKvvV8ZUq8FFB8/68ODWnu5sS3T+lUmRoKOM7NjR2UIX0/7YDrtauJr9fxQ0cwkug==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@4.0.28': + resolution: {integrity: sha512-nCtGJY43Kqwoyk0rYLj80a3eyXxcaWwyu+lYZDHgY+U6JbYYyvRdRTSy+XCDIB91rFH0Ul0eMDHmDr+YMYtrSw==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@4.0.35': + resolution: {integrity: sha512-bjYld/2KGPLt78kpqbya+fD4LYS7BqVQJyUjE3qAHrYB0FR2Q90BaWEVIBZaguTWXf/A8L6uG1zO1v9TxVlGWg==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@4.0.61': + resolution: {integrity: sha512-spROQutwsgm9ezXdoKP5PUPuHnNqMnuFqjioihmYDMJaaJnknYiEXYctH9hL4NJjaHuQBIl4ageCNsIZrQ+yCg==} + engines: {node: '>=18.17'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@5.0.64': + resolution: {integrity: sha512-BDU8rDR6mBR+na5U/Dj4B33LX980x200lqhBGRIOxxx1NFunoixuvvweqIB+sCsCoFC8cGCsa82Ce2fKoAPOqw==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider@3.0.10': + resolution: {integrity: sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw==} + engines: {node: '>=18'} + + '@ai-sdk/provider@3.0.13': + resolution: {integrity: sha512-ZPtVYt5QIJzOta1kdUiDuCx4HhFkvNPv/rvmZ2b1iXwybYjJsCnNYR4PAw4kW7rgVfDARvHXcU64efWuqNp6bw==} + engines: {node: '>=18'} + + '@ai-sdk/provider@3.0.19': + resolution: {integrity: sha512-5lWq7zSfRaU5ylDESn3sDQjgGl2AI1vjZKO/6JY3aFW70ct4zcP1kN+ZUYOuTXr28fVsYbyu2YFhddLdIgQFZQ==} + engines: {node: '>=18'} + + '@ai-sdk/provider@4.0.31': + resolution: {integrity: sha512-3wJnwVTFg8SwOyoZCv+ov7Re2GB+7IQnU5a5MYJACrtiWDDUHgqTBeeesq2MB2ddgojzL8hgWleltwpAgtUqfg==} + engines: {node: '>=22'} + + '@babel/code-frame@8.0.6': + resolution: {integrity: sha512-uMHhvmDmwFiLuiozaoRYTZHqMFuu3fem/X9JY78lohAuLoh8LSGGC8JqUzo2cVuBsBxkjMZNk56CE7ock8Xxkw==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/compat-data@8.0.5': + resolution: {integrity: sha512-YLsYoQMvL8l8WrGpN3Zj7O1wK5LEBN+cQtux7BcuHyxIXve724XG+zuJ1n3U1cUweRtTzQOA4IHbuQw3N34SZw==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/core@8.0.7': + resolution: {integrity: sha512-ZIsZWBG6Y1oa+8fkQVp0xeCdjCHBkXFCCIWrmg9SvejVvfcVQgKKRmGrBDWfM7rilhvnRoEuaqa5dkK7KB3pHA==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/generator@8.0.6': + resolution: {integrity: sha512-/pcanjdRsonCexCuxgGD8fKnBLLzk2i9uM4kmcmGyyev2R5YDs+rafMYZ89RvaGY1mW8T7C5au0TyYaEeHBGng==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-annotate-as-pure@8.0.0': + resolution: {integrity: sha512-NSpMkMsvvZqzThJ0p1B02cbtA2ObEyfBvq950bmNkyxsxvcxwhvvCB036rKhlEnuBBo30bOrk13u3FzlKSoRrw==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-compilation-targets@8.0.7': + resolution: {integrity: sha512-ilAZCdOOlOVA7dQbaFNw2f/59p6GW33NxTopc3DvEE3efp3ZXTrGX/yZScaKw8/vd9bq31Ag0EcXiLw32bAgJg==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-create-class-features-plugin@8.0.7': + resolution: {integrity: sha512-7ug3KrOhNVPPxFFLTel0/pMzimKzU/vTlNJKVL/dKguCpmNJZjjibyFbWg+Qs8QHmiIZPNuZ2UNnDGdHWGEpOg==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + + '@babel/helper-globals@8.0.6': + resolution: {integrity: sha512-OdnA/N52LhzFpeUuVz5YGuSWjc7TPHiFmVYZbPlSgExocO2GwbxVpSni9MVs5wwW+wZ4kPuwBEBN9pIPDYz1mA==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-member-expression-to-functions@8.0.5': + resolution: {integrity: sha512-GLe05QD98BkNFTkjaqeqF9QSRoHLKrrB4tpoplyQuuPrQJ72rtmkM4wvqJLX/sjZPqkbK5MUYSsuUTqdJoOVjA==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-optimise-call-expression@8.0.0': + resolution: {integrity: sha512-3W6satvtPuCUkUx63S2jMoW9EQNYkADgs1HTfufmL7gCmAulHMKupA/12WNz4A0GMMFn/YnWWwqOT9IZrJHQjg==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-plugin-utils@8.0.1': + resolution: {integrity: sha512-3PKFgjTyPlhFhorfP+SjKQxLViIL++zWjFOO4hGriYU+Bsm983DxEM1JmDRJVWXV0O9npu+xXRqz7Pbd3mh70g==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + + '@babel/helper-replace-supers@8.0.1': + resolution: {integrity: sha512-B1SZADIcy3tmH8CmWvj4SHi/oAPom4UL3uknTc2QRNsPVLFk/sPnZvQL/8kj7Y5omvjMqie0vklvs6XM4OLW5Q==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@8.0.0': + resolution: {integrity: sha512-xmCA9kP3IhySsqhzwIdWGlDN/1A4cCKNBO/uwZx/3YzmDoMePwno2Q5/Bq0q+tYaKbeF940YiKV/kaW8Mzvpjw==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-string-parser@8.0.6': + resolution: {integrity: sha512-+6HYEBnsDRZHJtUTAEfMQd0zMDqdFHS7C+5vAsEZqBUr3vEMWOWlHJ0Jz1gS8jJIlCvLsuA6ivmeoqzH936YcA==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-validator-identifier@8.0.6': + resolution: {integrity: sha512-HYx0YmuchRxRSpnjvcNffnPS8DCauKNmnumIuHG3jnQAVewRA7kfJGwF13ayEpSZs7s4R/oBH4eppuXcAQd5JQ==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-validator-option@8.0.0': + resolution: {integrity: sha512-U4Dybxh4WESWHt5XhBeExi4DrY0/DNK1aHpQbsrQXCUbFHuMweT0TpLEWKvaraV2Y6fS+ZXunsZ8zIuZIgvF2Q==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helpers@8.0.7': + resolution: {integrity: sha512-5dMj5kFwS2AY7Dt4PZp4px3c5ThMbbEa7tZfuHTncCGSFYq8uoA1ufDE1IS/lYpQedE+3+GQ3cPZUiplIu195w==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/parser@8.0.7': + resolution: {integrity: sha512-UkDwEbPO1px2JQSrdh4qIgaH1JgG7GO/pFeJkpxhDxIETkT/QvGpnigXIw75ViHYPtIgKITmVUJqLjiO+JuWjA==} + engines: {node: ^22.18.0 || >=24.11.0} + hasBin: true + + '@babel/plugin-proposal-decorators@8.0.2': + resolution: {integrity: sha512-+C6O6KKXU7BBq1GNaIkFJxrALUVGRcr+WeWm4OcuRl3h+l/CmNfcTLMrT2Lm3uvGBimBH/8pEBRrXJFLoO67Gg==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + + '@babel/plugin-syntax-decorators@8.0.1': + resolution: {integrity: sha512-NI+0S/6MvR6GlcQFwjDZ+WIc2qvG6TXN534lYs9llNldwW4b7Dh6KTtk030FA0xWdYGs4t1lWo+OEWN8wGB+Nw==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + + '@babel/runtime-corejs3@7.29.10': + resolution: {integrity: sha512-R4FKrg4Vy0hB7PfAxf9LOorEPd5/36SCIXPXAvjlQaQmPvtrjwoDXV15jsSm2ecsqBW1Iewwb7mEnG83xIEApg==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.29.10': + resolution: {integrity: sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==} + engines: {node: '>=6.9.0'} + + '@babel/template@8.0.0': + resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/traverse@8.0.7': + resolution: {integrity: sha512-bVV0brinsTWgc6ptSIoQo3GbITtl0VZAqEUJbHHcyfDPEu+q/fEvlYEa+6H85HoK8IdksKBFtKJbJFZ6Kff+zg==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/types@8.0.6': + resolution: {integrity: sha512-c+xgSWboV2pdwXP67BUWDVRHi2BO5Q3KwxyFVs7taVTY+fsK47/L51ZXQoV9rozHJDNHvJ4v4WEsI/IlxV2l2A==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@borewit/text-codec@0.2.2': + resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} + + '@cfworker/json-schema@4.1.1': + resolution: {integrity: sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==} + + '@chat-adapter/catalog@4.43.0': + resolution: {integrity: sha512-JRH40HwYIXdIiwSc/gNw65q5T/gaf691n4//2YOhjRE4YO9KzSFJ/N+RrTD3M8iGz2jI4Jg92wb6OAqfYsAkTQ==} + engines: {node: '>=20'} + + '@cloudflare/codemode@0.4.4': + resolution: {integrity: sha512-GL0IF7NiHwAC222riEYGX75NHcnhTornAPfRI0Mj3Ig7C1y9H89FL0xs+pdflIF74eecNkzynsA+JdCIkGvKeA==} + peerDependencies: + '@modelcontextprotocol/sdk': 1.31.0 + '@tanstack/ai': '>=0.8.0 <1.0.0' + ai: ^6.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + '@tanstack/ai': + optional: true + ai: + optional: true + zod: + optional: true + + '@cloudflare/codemode@0.5.4': + resolution: {integrity: sha512-/iyoiYNKYai961R1m704hmLbzg280C7ut3zZ2GIgaA1VSQMetjUmsS2t9YPCuLu2TZ8bOSoUtEz9UmNS4QmbFQ==} + peerDependencies: + '@modelcontextprotocol/sdk': 1.31.0 + '@tanstack/ai': '>=0.8.0 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + '@tanstack/ai': + optional: true + ai: + optional: true + zod: + optional: true + + '@cloudflare/kv-asset-handler@0.5.0': + resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==} + engines: {node: '>=22.0.0'} + + '@cloudflare/shell@0.4.3': + resolution: {integrity: sha512-6ZMKQZqdZeommh8LGFK5C2rep4byJfCuyjR4NBdMqn2wW9tbeDJORfDhP/No75MLx8nJeWdgeXvq3D2Ijpa0XA==} + + '@cloudflare/think@0.13.0': + resolution: {integrity: sha512-0Zo7jjPLLUv2q4FRu9ww3GrDFCOv73NgDl19yfjVGcYzAnxphiWRNaG1Sl7bwXcfWKZBUZ4SE2ckT3WEUjqzzw==} + hasBin: true + peerDependencies: + '@ai-sdk/react': ^3.0.204 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.17.1 <1.0.0' + ai: ^6.0.182 + react: ^19.0.0 + vite: '>=6 <9' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + vite: + optional: true + + '@cloudflare/think@0.14.0': + resolution: {integrity: sha512-YQT1FJx6LwFrtsy3yr3Wd9QWVRIuijAxtFzA7JAOqJOO3ZBSnBJPlJ6S8OftojPU4GcIxEkyFNUyCgHD3jEc3g==} + hasBin: true + peerDependencies: + '@ai-sdk/react': ^3.0.204 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.18.0 <1.0.0' + ai: ^6.0.182 + react: ^19.0.0 + vite: '>=6 <9' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + vite: + optional: true + + '@cloudflare/think@0.15.0': + resolution: {integrity: sha512-vI7YhGRrxbsnMEA6gVWD7aaWxa9dZOJBFuc+d9DZVLD7jfasO1egJ6LbS7VS6kfjCBETIzudi+wlmS3wYISEYg==} + hasBin: true + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.18.0 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + vite: '>=6 <9' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + vite: + optional: true + + '@cloudflare/think@0.15.1': + resolution: {integrity: sha512-BAMVRoBArhszewE0ONcq6sNxfB0QsXIZkhdZYl+6hXdUC/tHShRK1ZDaGhHuWhDBBGYsPY07ploFy4WOmCLkwQ==} + hasBin: true + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.18.0 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + vite: '>=6 <9' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + vite: + optional: true + + '@cloudflare/think@0.16.0': + resolution: {integrity: sha512-SVUJR+ENNL/eu7L5fNZCYALd72DRJYSiu7efNyr6hzNwFXYZSZz0Ecz06DoPLfN6k+F5ABO+0CHLVLAfAtr7dA==} + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.20.2 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + + '@cloudflare/think@0.17.0': + resolution: {integrity: sha512-tnfMZSqSz1dhfBx0io/mXMJE2huwJc2kTPAkx55y1bTUQwt9A2uONBmN1FixNsI9DFp1zXJDzcO0juGFKfTyLQ==} + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.20.2 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + + '@cloudflare/think@0.18.0': + resolution: {integrity: sha512-eN3gZvO05UPucAaQ9GfIu5iKhMeRKqd+NzxfNdi3rhbAHhsTC3ckxPnXNlBmr8Pg0zcvaJK69KhWPv4AySeexQ==} + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.23.0 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + + '@cloudflare/think@0.19.0': + resolution: {integrity: sha512-7xYaVeQJA4Xnwuo2R5/zhbUjWftvKzVjdsZnOSYjo+BqJ+hbizemW8fCt1QTTP+TDixgXXiOQNlOmyNJXjTYUw==} + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.24.0 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + + '@cloudflare/unenv-preset@2.16.1': + resolution: {integrity: sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==} + peerDependencies: + unenv: 2.0.0-rc.24 + workerd: '>1.20260305.0 <2.0.0-0' + peerDependenciesMeta: + workerd: + optional: true + + '@cloudflare/vite-plugin@1.45.1': + resolution: {integrity: sha512-C+iDpO9pVH7IqrjdYtUV+obcTAdpiNk0OSinGEZZyd2ZWyGVjGk7iJ2p3xpMBpZuTa1I4hfAECNp0yN/8f3PIQ==} + hasBin: true + peerDependencies: + vite: ^6.1.0 || ^7.0.0 || ^8.0.0 + wrangler: ^4.112.0 + + '@cloudflare/workerd-darwin-64@1.20260714.1': + resolution: {integrity: sha512-ZWXqAN8G7Cx9hMRQuk+59ziJhR3j1F4iO+Qs8aHdfKZ3Dq5Yi/57xvkJTgCGBnW1YU/L78r8f6HEy51bwbTpNw==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + + '@cloudflare/workerd-darwin-arm64@1.20260714.1': + resolution: {integrity: sha512-tueWxWC3wyCbMG6zRAxsMXX0YLgrRWbiAPYFQ2uJ7dUH8G+5E7UTWaQS9B1HdJ0bpKFW1NWxhs1o2noKVFSUYg==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + + '@cloudflare/workerd-linux-64@1.20260714.1': + resolution: {integrity: sha512-1VChTZRb0l0F7R4e1G5RtLKV4oFi6x+rQgxh2+yu887j3l/3TLgatuv1L8/5zhc9gKEhATTxOh0e52Rtd9dDWQ==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + + '@cloudflare/workerd-linux-arm64@1.20260714.1': + resolution: {integrity: sha512-rMm3G+NirG2UdgHIRDdF1asNC6FqgIzZzkRG+VDhhDGcVxAQwvrMT1E38BivEvHr3G04MB4AfhcOczX0+GtRkQ==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + + '@cloudflare/workerd-windows-64@1.20260714.1': + resolution: {integrity: sha512-cGqnU3Hg2YZS/k3SAqrMp1DjpdsyFde72tWltdl6ZT9+SFz/Zrk/8gyTU1TcxC4YApXeNVH5TyU5cOGPgUJ0pg==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + + '@cloudflare/workers-types@5.20261019.1': + resolution: {integrity: sha512-llvvy7WBVhK+OfykyBkG9A7OgsGvgwHSNyU40XGVkiy/xVFy0t/xflyhEBHT+U59yQECZQbmcZsJtqCNnLpIRg==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@emnapi/runtime@1.11.3': + resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} + + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@hono/node-server@2.1.5': + resolution: {integrity: sha512-MgP/I06GdvsilDspMk/qmRzpk8LOUStP6jFAbSRi40W09DhoyUn+Mj7eyKICPqeYKybOjVFLVIAQzvu1bfIa7Q==} + engines: {node: '>=20'} + peerDependencies: + hono: 4.13.7 + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.35.5': + resolution: {integrity: sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.35.5': + resolution: {integrity: sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [darwin] + + '@img/sharp-freebsd-wasm32@0.35.5': + resolution: {integrity: sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==} + engines: {node: '>=20.9.0'} + os: [freebsd] + + '@img/sharp-libvips-darwin-arm64@1.3.4': + resolution: {integrity: sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.3.4': + resolution: {integrity: sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.3.4': + resolution: {integrity: sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.3.4': + resolution: {integrity: sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.3.4': + resolution: {integrity: sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.3.4': + resolution: {integrity: sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.3.4': + resolution: {integrity: sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.3.4': + resolution: {integrity: sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.3.4': + resolution: {integrity: sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.3.4': + resolution: {integrity: sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.35.5': + resolution: {integrity: sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.35.5': + resolution: {integrity: sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==} + engines: {node: '>=20.9.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.35.5': + resolution: {integrity: sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==} + engines: {node: '>=20.9.0'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.35.5': + resolution: {integrity: sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==} + engines: {node: '>=20.9.0'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.35.5': + resolution: {integrity: sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==} + engines: {node: '>=20.9.0'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.35.5': + resolution: {integrity: sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.35.5': + resolution: {integrity: sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.35.5': + resolution: {integrity: sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.35.5': + resolution: {integrity: sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==} + engines: {node: '>=20.9.0'} + + '@img/sharp-webcontainers-wasm32@0.35.5': + resolution: {integrity: sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==} + engines: {node: '>=20.9.0'} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.35.5': + resolution: {integrity: sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.35.5': + resolution: {integrity: sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==} + engines: {node: ^20.9.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.35.5': + resolution: {integrity: sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [win32] + + '@jridgewell/gen-mapping@0.4.0-beta.0': + resolution: {integrity: sha512-JdGNkbE4GlNPYQhM0L95fBQr7ctLZJ276QXQLTad4t1oSdnnCI3fDq9DW3BqYAWv8Wc3+HS+4Gsii1oPMCfz1w==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@mixmark-io/domino@2.2.0': + resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} + + '@modelcontextprotocol/client@2.0.0': + resolution: {integrity: sha512-8f1OghQ2rjzIOfqgUCP+8GiUWqRs89njoWLNqAe8kWmDePv3s1fZXseej+QXemssEuuOvLLmLO/kqM3IQHtISw==} + engines: {node: '>=20'} + + '@modelcontextprotocol/core@2.0.0': + resolution: {integrity: sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==} + engines: {node: '>=20'} + + '@modelcontextprotocol/sdk@1.31.0': + resolution: {integrity: sha512-UvTMgnNlnIBO/22ob2RcVGDlcvOslQs8T59+FTGdA0L27a39fdGF/EDETNtDVK4DZGpwomlsYpRdA8UXcVL/pw==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + + '@modelcontextprotocol/server@2.0.0': + resolution: {integrity: sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==} + engines: {node: '>=20'} + + '@mongodb-js/zstd@7.0.0': + resolution: {integrity: sha512-mQ2s0pYYiav+tzCDR05Zptem8Ey2v8s11lri5RKGhTtL4COVCvVCk5vtyRYNT+9L8qSfyOqqefF9UtnW8mC5jA==} + engines: {node: '>= 20.19.0'} + + '@napi-rs/lzma-linux-x64-gnu@1.5.1': + resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==} + engines: {node: ^22.20 || ^24.12 || >=25} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@nodable/entities@3.1.0': + resolution: {integrity: sha512-LsS/DjHr+uDM647Gru/cA8+J3a3HfhttwCKLyuoyN7yXTFCxKBtSgMQBvrW9yNPa2/zDRUNuGPaH5QUFoa4arQ==} + + '@opentelemetry/api@1.9.1': + resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} + engines: {node: '>=8.0.0'} + + '@oxc-project/types@0.154.0': + resolution: {integrity: sha512-KYOUGQFlLWR+s4QMV2Q9ko38TZm7EdO87Qm7rvZLqk/webse/cDjtyxKhg/47l0byCbs/k46LT8qc4PKjAikzA==} + + '@poppinss/colors@4.1.6': + resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} + + '@poppinss/dumper@0.6.5': + resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==} + + '@poppinss/exception@1.2.3': + resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + + '@rolldown/binding-android-arm-eabi@1.2.14': + resolution: {integrity: sha512-aWR+XKH9+rW7m5fWq/5360J3mHycrx/o6xZM2DQFdJnTMdyP7/WzxPjhtLbVWdKo2y612/4U1bWqb3HQhiF7vg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@rolldown/binding-android-arm64@1.2.14': + resolution: {integrity: sha512-QiVxHofl6A8lQU7WAtOUY4QMVZXohxwz7WJJoeh8NBEUyKfIkMRKhYyq8az/1RypNiIXzNTtiS6KwHz0erxYRQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.14': + resolution: {integrity: sha512-lTQOzHuBIooh3jIr5XINQkjPGEuGy+Dsy0meXDr6Sjty0b99kYgGh4uBC/8mJX1T0kC8d6S0aPP1Y+bHkh6aBw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.14': + resolution: {integrity: sha512-hyMKEGatjmBYCs/Q4sbIcL/GqpFEqsX3wc+HYVQ/85A4rxc1o7rPm4DUI4GV4k/h0ITddwFSGpqQunI14GXjTA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.14': + resolution: {integrity: sha512-u371GbXoVXrEgP20PwzoGNOdAOqAMhzo19JzzY+V4YmmnC+DTOoqdbMu+O+54emM59Mik/UdrtWgcuEDKWRPKA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.14': + resolution: {integrity: sha512-BqwKsdZQf6EqVWr8fv2MrDYzAvOZ7+NYFSJESRGs87fkseEhs0TU9TXgRJTkZoRRkxTizyEg1LKUXfU3/78uqg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.14': + resolution: {integrity: sha512-SD9kY8M009x/7s57Z1dgUVlP5+uYBgKQK0Tkr1WIWngrtUJmRCW1RJFMY7QDla2khXhmg2i5Io7MUjcmZNZ/KQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.2.14': + resolution: {integrity: sha512-BJ2CL19M6uuWesMgnqJzgxoI+N+eV7b0A9O9vLV42y+gitC41fNa8KElau1tHVzuLWX5GzEuxMPhAO0tQXQMkg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.2.14': + resolution: {integrity: sha512-4+Kl8daPV8NDHaD7mfCcc1pRM+Qg7ab8DyMm5FG5WoZgv4h2i3KFN1CybYBNbQqmuYm7ftJLvmMI1eHYJ22S/Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.2.14': + resolution: {integrity: sha512-V/h8ePq1fKDrmtFMz6xcCN3DKvuvMRrwwD1q0PkBeeo4DpK64biaKvqWGVxqCeYKqeRk7gE7/iKPxLCn08O97A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.2.14': + resolution: {integrity: sha512-WxalXzgrLVpKC93xfpaJ3gCXUWzeCr+FRCbDVD2mUAy4L6Vo3lNVz0epUEUpxPWJkLNYUwM4OSIikv36OJ9mLg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.2.14': + resolution: {integrity: sha512-3G3tnAmTpdk9jO3GQtyHXqeFD2SlecfTws/Y3M2mmj9nMBwwuLT4kur8sZKeu7ENUHSpVO3cIsm5A52LEWWwlg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.2.14': + resolution: {integrity: sha512-qyr5XiNGxm2ytx17vvtcJ9nXn6v1gENETi503bJx3OGwZ1tSonj7BosxbMa/xeAfSl5iS9X6KjEWYXLu6v1L7Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.14': + resolution: {integrity: sha512-oA4o5o0S2yB199YyYXDzKUv1Z56Rc+mgOjwm7Z/vJ9Z8igiDPYvoOuDyo6g7AK/ZaF09nPhDKVnGBcYHO11GXA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.14': + resolution: {integrity: sha512-9mE94bf2GZUaR/fUSXCMpBoWkctu421Mi0ORpm4zqfbkjKep7RxzPFa5etcGs5h+2KApoWBOA/hAJa/7saGgEQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/plugin-babel@0.2.4': + resolution: {integrity: sha512-ygmm2j/mN+aCvstHo0x3IOu4uc6LqXT9SJ3q4kpfG/+Yhfz0B+E47FITcC0FljZADwUFARP6E2kiE+Lc26D8wg==} + engines: {node: '>=22.12.0 || ^24.0.0'} + peerDependencies: + '@babel/core': ^7.29.0 || ^8.0.0-rc.1 + '@babel/plugin-transform-runtime': ^7.29.0 || ^8.0.0-rc.1 + '@babel/runtime': ^7.27.0 || ^8.0.0-rc.1 + rolldown: ^1.0.0-rc.5 + vite: ^8.0.0 + peerDependenciesMeta: + '@babel/plugin-transform-runtime': + optional: true + '@babel/runtime': + optional: true + vite: + optional: true + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@rollup/rollup-android-arm-eabi@4.64.12': + resolution: {integrity: sha512-Z8lz+5UOiCJLonjeqwJlhUtHA/Sr6R1AidkccQxdWF0nigNzP81aLoU+udgOaGfL5s1uzFXzcux/pCwGAMu0lw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.64.12': + resolution: {integrity: sha512-+tKxNa2psFmiTb0KfXlXs4Yj7vkEhzAvZ0DrQ5+0gWHQJM10jSleQ3l1FIVm5uvD53YM8lHfM4mgCLDDN9f1Gg==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.64.12': + resolution: {integrity: sha512-iiripdfvyRBugV55/Dk7GplNXQtN/PG85OcKeveU1z2UkTg0MofbBF1qk//qgPWiqJbVvQcXAVCfE56oDGO4EQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.64.12': + resolution: {integrity: sha512-BmATib8swSMAagWNIfDZMnb+k34RXR4bbGOUfZgK8lLlniuMyVoSDDXCOGkdhtUmBXL4aygDh7bhjQ+TmhTvIw==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.64.12': + resolution: {integrity: sha512-GzrO0CiUq8vcAI/hYJuIcp6wNm3T3YhOpumYtf9Z3Fz+cfN1VESCVfy7EPcM3/m2K8l+Gn2U+4XtNZjwhUXctQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.64.12': + resolution: {integrity: sha512-Dpta6gigm4o6SYioXtTkZBlGLA/Sl6OpzgLqY+51uafJE2blPejAtR1w82CVLPN+F9cvo1+/em92x/zcOgY0uQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.64.12': + resolution: {integrity: sha512-YpeDwQ5uFaogRvytNC8RK0keDO65kI5wNEhGSs+4GiJc3KHhxj4j5cnQh2nCu9ybJj6RP0/ycB6bkN0yFJ9I+w==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.64.12': + resolution: {integrity: sha512-LQrB3/sImIr1ycrlEyaApOLH1rAy8JV4/dH4eoK817aWATdcs4fESXz53/w72NwDnwPM5zEUpoL7socH4ZDnwA==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.64.12': + resolution: {integrity: sha512-iAF2iYu9S4SBfNsb4k0ewNBjO83WxHEltIuKQBGMzEKFgrYfmJn+gatBDXR2t/0zJN0UW0kzR4rfvQ1UHzkZ1A==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.64.12': + resolution: {integrity: sha512-0MQdRtdbirJCXPIVeW/hd/LXLR8Qz96pc+2EBptuuV5q/zSGOzND7SZt8gBTE58NC9cUG/8UxcUXQiKRZ2WzzA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.64.12': + resolution: {integrity: sha512-yGDEwn0AGnrY/KCz2oY8R9KKNiQnTcwNuCWXeSXF0VLxXzlqoCgaS5QHsf1lbQvKWwPuN2Czkjk1wXRCBONTOQ==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.64.12': + resolution: {integrity: sha512-AjlbD0efZEhHaJ3bsNjxSFDoguNq6VZvC+FKGJGBCA+ZN7BrZq2TuuSWFa6AI8IpOeuvhp2LoYcP7jiZwmtU0Q==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.64.12': + resolution: {integrity: sha512-sDW0CiPoUCEEUV25uBG5sJ2gKe75DJqLpj91m1eK1vKffywyY7v4i6q1450ZuR6QW4NArXg7JpbMGgKU8di3HQ==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.64.12': + resolution: {integrity: sha512-VTQYUhMjl8kv999VuYqScgv7P9cR9KuxI/6bkUsEa3bsswqG0+otFjuLZmJ1U+ffEP4IAz0jxOeV0DX6NRBhjg==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.64.12': + resolution: {integrity: sha512-ppsKwpSjNrzJ8hge3Z3uiCcoRgAAQk2tU7auy3MFF348ffWRldFPnWIT/a/enK7huijlTfnwn4DYpDoapEb45A==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.64.12': + resolution: {integrity: sha512-Gc3cVRC1trFH+GFWWTsJz6YuD4u75fzr/q99jqQGimonN/zvN6Wecck5WGzllOHj+XYXHcq0Ibor0tanGjfI6A==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.64.12': + resolution: {integrity: sha512-pjmDTFStvwFE3shTeUDvSDiSp8/qAf5bQXejcEUDDavWz4jEhTIpCdpS06G0PEwSCSNK0Lngjz2v9l4hk3Z74A==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.64.12': + resolution: {integrity: sha512-mkbjxPqpR91u1JD7xY4aLZhr/Mqka4/RqGcG4WNGgN/lC1o7TzyCyqJoSJXp9qVVxMwpJGFlEF1VlERb+Ghw1Q==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.64.12': + resolution: {integrity: sha512-vIeut2LkuVc3gcsawLJPahNAzvzBcFRhu2O+yVb//BuQKz7PIItMF0piXRbN/lIDO3d68TSDd368Vg6YwgTybw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.64.12': + resolution: {integrity: sha512-3Sx+D3r9oPkTdNUcPrIRM2Am+vzEV6VGWoImHG4ZVK2jJeOW+eDjLeTm6nvu/z/m0fiX2YmGLXIypblc336MXg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.64.12': + resolution: {integrity: sha512-Nn2xh0teFnl71EiiUrKvECWcdGXtWF8q0uGclYwXGVw6QClGAcME0/bJSGdK+xIvd6MLEKYmjkTUvCBV+7m5Kw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.64.12': + resolution: {integrity: sha512-n1/0H9TS+kBa4xp6n9aV7yiynBNfmerjkj2nAMIfY0ZHv1zShWRXnsAuAPAH0sfEK4ZSMK+z24q2RjAPFLCN1w==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.64.12': + resolution: {integrity: sha512-AdlDbQpsLfGlsHr1NfLZFtdnvxCKNp9TwlYVYExs8JJLWjLafUQEKJk0r9zUbmU57mw9nglMEvzqPHuLWYmaKw==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.64.12': + resolution: {integrity: sha512-u5SSUJBHod51UamjkigSr+JPre6xMy5vaWTTV2K0SnFG4RuKyYpf66dTSLFKX2cwaldpwyBurXPUCxq8riQMEg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.64.12': + resolution: {integrity: sha512-j5rXD4R/4DM5+V991AA9xOnG2Rwu2g3p5TPgu1Eu7apju0NUrLl+Bn/KpWc6wYJtlXqzwz1r+LNV1JeBU4VGvw==} + cpu: [x64] + os: [win32] + + '@sindresorhus/is@7.2.0': + resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} + engines: {node: '>=18'} + + '@speed-highlight/core@1.2.24': + resolution: {integrity: sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tokenizer/inflate@0.4.1': + resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} + engines: {node: '>=18'} + + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/gensync@1.0.5': + resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} + + '@types/jsesc@2.5.1': + resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@vercel/oidc@3.2.0': + resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} + engines: {node: '>= 20'} + + '@workflow/serde@4.1.0': + resolution: {integrity: sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==} + + '@workflow/serde@4.1.0-beta.2': + resolution: {integrity: sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww==} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agents@0.17.4: + resolution: {integrity: sha512-K6YRbpD3VcwdTOPBlDgI4dILAwkhXo5cdxTlVF0IvUwQEKfMPawmH8E/QMXTN8CPGHqVYgYFACxTyk6nKlK+vg==} + hasBin: true + peerDependencies: + '@ai-sdk/react': ^3.0.204 + '@tanstack/ai': '>=0.10.2 <1.0.0' + '@x402/core': ^2.0.0 + '@x402/evm': ^2.0.0 + ai: ^6.0.0 + chat: ^4.29.0 + just-bash: ^3.0.0 + react: ^19.0.0 + vite: '>=6.0.0 <9.0.0' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@tanstack/ai': + optional: true + '@x402/core': + optional: true + '@x402/evm': + optional: true + ai: + optional: true + chat: + optional: true + just-bash: + optional: true + vite: + optional: true + + agents@0.18.0: + resolution: {integrity: sha512-ozQCDZrJerDMW/2/X3N+y6yzB4PAfiMtPN4jhK5fD+CFdYfc35k0mqNf/GTWzMA6Pc7WekOB/nFaAlIMrH9WvA==} + hasBin: true + peerDependencies: + '@ai-sdk/react': ^3.0.204 + '@tanstack/ai': '>=0.10.2 <1.0.0' + '@x402/core': ^2.0.0 + '@x402/evm': ^2.0.0 + ai: ^6.0.0 + chat: ^4.29.0 + just-bash: ^3.0.0 + react: ^19.0.0 + vite: '>=6.0.0 <9.0.0' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@tanstack/ai': + optional: true + '@x402/core': + optional: true + '@x402/evm': + optional: true + ai: + optional: true + chat: + optional: true + just-bash: + optional: true + vite: + optional: true + + agents@0.22.0: + resolution: {integrity: sha512-dIy/BRdO5GSqdOIp0pmkcLmHCCxIKb4RBByXFXmXG6Nc6WBSNYRXoLLDvWj2fJAfi4l5/OndJjZuBAP0vW0DZQ==} + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@cloudflare/codemode': '>=0.5.0' + '@modelcontextprotocol/client': 2.0.0 + '@modelcontextprotocol/sdk': 1.31.0 + '@modelcontextprotocol/server': 2.0.0 + '@tanstack/ai': '>=0.10.2 <1.0.0' + '@x402/core': ^2.0.0 + '@x402/evm': ^2.0.0 + ai: ^6.0.0 || ^7.0.0 + chat: ^4.29.0 + just-bash: ^3.0.0 + react: ^19.0.0 + vite: '>=6.0.0 <9.0.0' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@cloudflare/codemode': + optional: true + '@tanstack/ai': + optional: true + '@x402/core': + optional: true + '@x402/evm': + optional: true + ai: + optional: true + chat: + optional: true + just-bash: + optional: true + react: + optional: true + vite: + optional: true + + agents@0.28.0: + resolution: {integrity: sha512-5nYoykTqL6HWLwRyPP9XL4triRg+kkc6W1Ovt58lMz3oLbChRst6GWQVU3LvLgve8YIbo1SvQp0IR4TOrxAD6g==} + hasBin: true + peerDependencies: + '@ai-sdk/provider': ^4.0.0 + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@cloudflare/codemode': '>=0.5.0' + '@earendil-works/pi-ai': ^1.0.0 + '@earendil-works/pi-durable': ^1.0.0 + '@modelcontextprotocol/client': 2.0.0 + '@modelcontextprotocol/sdk': 1.31.0 + '@modelcontextprotocol/server': 2.0.0 + '@opencode/plugin': ^2.0.24 + '@opencode/sdk': ^2.0.24 + '@tanstack/ai': '>=0.10.2 <1.0.0' + '@x402/core': ^2.0.0 + '@x402/evm': ^2.0.0 + ai: ^6.0.0 || ^7.0.0 + chat: ^4.29.0 + just-bash: ^3.0.0 + react: ^19.0.0 + vite: '>=6.0.0 <9.0.0' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/provider': + optional: true + '@ai-sdk/react': + optional: true + '@cloudflare/codemode': + optional: true + '@earendil-works/pi-ai': + optional: true + '@earendil-works/pi-durable': + optional: true + '@opencode/plugin': + optional: true + '@opencode/sdk': + optional: true + '@tanstack/ai': + optional: true + '@x402/core': + optional: true + '@x402/evm': + optional: true + ai: + optional: true + chat: + optional: true + just-bash: + optional: true + react: + optional: true + vite: + optional: true + + ai@6.0.202: + resolution: {integrity: sha512-14O7uyHVa5lXyt1RzduRqM1zwOnLBN+EaE+btWiP2R7GLHd5oh+Z9uaebR785V/Y2hXlxvuQGsw2Gj6iHpkxsg==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + ansi-regex@6.4.0: + resolution: {integrity: sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==} + engines: {node: '>=12'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + anynum@1.0.1: + resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==} + + async-lock@1.4.1: + resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + aywson@0.0.16: + resolution: {integrity: sha512-xLFICM6OgSMcysNHCgrhri7hpcn0TfuyU5KxtjpIAJAUuD0Bjph2pSkLgxjn45iQBjBxs4S5Fq+RmXhIYuQtNw==} + hasBin: true + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.11.30: + resolution: {integrity: sha512-YJs6Pz17RMNv8HoyKREtCY38E3BV1nPkWVmIb+XN1uHC1Vqt3KZCH/uJH9ZKRoiKb/icZ6tvehyee6RZNbFfRA==} + engines: {node: '>=6.0.0'} + hasBin: true + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + blake3-wasm@2.1.5: + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + + body-parser@2.3.0: + resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} + engines: {node: '>=18'} + + browserslist@4.29.4: + resolution: {integrity: sha512-2TcbbiwXEq+N0kD36tykpCfyyQigUXmuwNQbnPp4Xk4PX9JOqVIKjJlIDjpH7uY6tmRGoAd+apeT1p60T8wsdA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + caniuse-lite@1.0.30001817: + resolution: {integrity: sha512-uZ1JG80BwhtMalIAGPxPfmNhHyd/B/nTdr3hITWlRamSyAdUStP1Gop01e7SD5q6J90ixJvWDbvmiFVfDgn4bw==} + + capnweb@0.12.0: + resolution: {integrity: sha512-jgZ/LMtMVTi+RVlooIslH78Gg23XbDTdvcLghWx3oz17D6u5GuJARt+uhZk/wcTo+f81eeabfnow4d3zLBj+JQ==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + chat@4.43.0: + resolution: {integrity: sha512-9ICxMewK1+4J0pEbR7eMBTh3JCL3NkyDHAgGrU/gblyyw/+QUcwFHCXIoQMt0Xlyup1c5smS0/gYytTt8NVc6w==} + engines: {node: '>=20'} + peerDependencies: + ai: ^6.0.182 || ^7.0.0 + workflow: ^5.0.0-beta.35 + zod: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + ai: + optional: true + workflow: + optional: true + zod: + optional: true + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + clean-git-ref@2.0.1: + resolution: {integrity: sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==} + + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + + content-disposition@2.0.1: + resolution: {integrity: sha512-e+H0ZXHSWYrENhQzw1LPuP4oF5MzVKmDU6d3hxlvaPEYLLg62MxtQNPRx4SYSuYJSBUgnQIG4HIN2tEtNv7Dog==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + content-type@2.1.0: + resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} + engines: {node: '>=18'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + core-js-pure@3.51.0: + resolution: {integrity: sha512-NE4SFDJ+qzQeqHG2vVSNwopzS6zZNPYJ5kinIqs+OofTqGzOmICgT89E/yvS9XY7rwb3eU1utWXTJ9nVFqv74A==} + + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + create-think@0.1.1: + resolution: {integrity: sha512-C8+k9fPArd1B0nnDUV83Fjw7hzJyaY+LN4v3Va+k4enMlSw0ZvyJERjJwntcp+1Snos+sy07SQYpV+1k10zARQ==} + hasBin: true + + cron-schedule@6.0.0: + resolution: {integrity: sha512-BoZaseYGXOo5j5HUwTaegIog3JJbuH4BbrY9A1ArLjXpy+RWb3mV28F/9Gv1dDA7E2L8kngWva4NWisnLTyfgQ==} + engines: {node: '>=20'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + dc-browser@1.0.4: + resolution: {integrity: sha512-7oEtnzNlcE+hr4OvO3GR6Gndgw8BhW+wKOEwMqSleyY7N29jbAxzyW5BaJl7qBCw+6OIxfMWtY0T+6dxq8RWLw==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff3@0.0.3: + resolution: {integrity: sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==} + + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.460: + resolution: {integrity: sha512-rRaVC7bNUyGsL+GMtmZfv3AfgG6za7gE9v5bT0PIbjEerddA0IQ+tCK05NFAXqCpNlrxBZqbFqquyxHRQONHTA==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + empathic@2.1.0: + resolution: {integrity: sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==} + engines: {node: '>=14'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-polyfill@0.0.4: + resolution: {integrity: sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ==} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + eventsource-parser@3.1.1: + resolution: {integrity: sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + + express-rate-limit@8.7.1: + resolution: {integrity: sha512-2FXbqkygil3mZiXzEtM0IjE/UBmBNot0J1GEVrJT4JbrvwOSoEtqtO+wHbiMQELWe1eNvHoYRg2dkjOid+6JkA==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.3.0: + resolution: {integrity: sha512-qCqy1xSoaugxOD4IVHb1ZWdkvCF2W3aE2okKouWj8VwJ+ztskSiXoBnCSJqfKT+cVPJhuJqe9YLbY425+Zh00g==} + engines: {node: '>= 18'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-uri@3.1.8: + resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} + + fast-xml-builder@1.3.1: + resolution: {integrity: sha512-pIM/1n3ntFXKYrUZwW7QCK0gAW7XY+wzj1YMIV3tLDvPj/V+zTGJK5e3/4WJfwj0qWw2ElNXiTixda/R+3YSug==} + + fast-xml-parser@5.11.2: + resolution: {integrity: sha512-R9iDuNrQYeQut46cn2r2wHKn4HYzVDvDm5J1wW+koZewykv0yuO2HChTYeZtrULyHIDM9cj9TUXloCsueCQUog==} + hasBin: true + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-type@21.3.4: + resolution: {integrity: sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==} + engines: {node: '>=20'} + + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + flru@1.0.2: + resolution: {integrity: sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog==} + engines: {node: '>=6'} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.7.0: + resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + guarded-fetch@0.1.3: + resolution: {integrity: sha512-PSaNyJk8VJlUVEhMHPXT/Z/WgNrLBh43WaYQJiu1qvyCuPQA+kgFMNmAOxI3GU3uXrCkO/xRW11XjcswrksYOA==} + engines: {node: '>=20.19'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + hono@4.13.7: + resolution: {integrity: sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ==} + engines: {node: '>=16.9.0'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@6.0.0: + resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + ip-address@10.7.1: + resolution: {integrity: sha512-4OUAqU9Z1i3vCnS05hzGiFnEMDpQ+62pAD/MVQOp83fYyNC8GleCqaS0QikQBmcWCrKFiUs/B8ztRRiYOAXuCA==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipaddr.js@2.2.0: + resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} + engines: {node: '>= 10'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-unsafe@2.0.2: + resolution: {integrity: sha512-HgbIHPBH0KHHCcjLfGsCvhtPTVxjaAZlXjwdz7/GQC40SjSe4sfQsar8J5VFo8JOSbarkpV0OLG95bbaNd9aAQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isomorphic-git@1.44.3: + resolution: {integrity: sha512-xlEIMsVUrMfOR25F4jWB9He9s/rUHWsgfJJJ3zpdwFssv9X2QfoIUyYH9CEFok9yk2tx2UDipj2gJ+KVvV/qGA==} + engines: {node: '>=14.17'} + hasBin: true + + jose@6.2.13: + resolution: {integrity: sha512-7TIg10ZE1x82YediN+lcrPNvGMKge9yFHQD+Qho/b8y2adfugU3AsvvHfxV0fzyFllT6l9xCjf4RWY9g/Z9PJQ==} + + js-base64@3.9.4: + resolution: {integrity: sha512-PtOMXpEGuP0RRiRXsjzHzl44dMHxSu2CPvAhinupR1tBa88me+1DPqsobl7eupn5UukjLkln1ZnAOAOXOrYG0Q==} + + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + just-bash@3.6.0: + resolution: {integrity: sha512-2COjEgcHdqKXeQSiNfPAHmpwQx4S8wATaIwog83g2t645U5tom6FED4CBBdr3M+0ioX4xZ26eODw3/nD6RQ6xw==} + engines: {node: '>=20.19'} + hasBin: true + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-find-and-replace@3.0.3: + resolution: {integrity: sha512-xPgpDNl0/OXHsI7TlaIs22lWnH3KlpvZdXG1ET/m/YT2Hhdkx8lJV4kLphE6l9simyM4KPDFBwas08BgEob6Jw==} + + mdast-util-from-markdown@2.1.0: + resolution: {integrity: sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.1: + resolution: {integrity: sha512-OuJHqvr455pwu2OaOrir7dbzqs4jlWKOtlu9L6GjcIjjQwNyw02VntQsr/Ek6/A13vgnXfUhBekWRUP1OkNivw==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-markdown@2.2.0: + resolution: {integrity: sha512-2Jn/ADrHFFyyniBMi0bncTbJqU78K3/TEYvzvwrWWzD9MYPUa/Gm4r3nOeKFQg/PDM5BsbDYdc8ackW4NTY6NA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + media-typer@1.1.1: + resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + micromark-core-commonmark@2.0.4: + resolution: {integrity: sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.2: + resolution: {integrity: sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.1.0: + resolution: {integrity: sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-edit-map@1.0.0: + resolution: {integrity: sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.3: + resolution: {integrity: sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==} + + micromark@4.0.3: + resolution: {integrity: sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mimetext@3.0.28: + resolution: {integrity: sha512-eQXpbNrtxLCjUtiVbR/qR09dbPgZ2o+KR1uA7QKqGhbn8QV7HIL16mXXsobBL4/8TqoYh1us31kfz+dNfCev9g==} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + miniflare@4.20260714.0: + resolution: {integrity: sha512-MYlTCLdWCPqvrYY2uLwOjXwmglXuiHE3TGGkbOW4BwjUPa1r07E0iuHwrNDIs/sxK21r+o90Jx58AV2KeNdJZw==} + engines: {node: '>=22.0.0'} + hasBin: true + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minimisted@2.0.1: + resolution: {integrity: sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==} + + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + modern-tar@0.7.7: + resolution: {integrity: sha512-t9VmxaqrmANnEOBhpSDI6HD192Ge48k8vmWqQQL7hSFEqHEYwZbbsu49+aKLWZeRvFs3j1pMhXOqqF4kPlvjkQ==} + engines: {node: '>=18.0.0'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.20: + resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.1.16: + resolution: {integrity: sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==} + engines: {node: ^18 || >=20} + hasBin: true + + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + + negotiator@1.1.0: + resolution: {integrity: sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==} + engines: {node: '>=18'} + + node-abi@3.99.0: + resolution: {integrity: sha512-lLdwkeg2XUVPTHqWjPltTxH81zbQNbUWC+AEb9ni50KjxkUzAAx1HGtMT21sbntzfUGfIphhcklvs3imJeqDXw==} + engines: {node: '>=10'} + + node-addon-api@8.9.2: + resolution: {integrity: sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==} + engines: {node: ^18 || ^20 || >= 21} + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-liblzma@2.2.0: + resolution: {integrity: sha512-s0KzNOWwOJJgPG6wxg6cKohnAl9Wk/oW1KrQaVzJBjQwVcUGPQCzpR46Ximygjqj/3KhOrtJXnYMp/xYAXp75g==} + engines: {node: '>=16.0.0'} + hasBin: true + + node-releases@2.0.59: + resolution: {integrity: sha512-5qr2okC4ItAI0hG5SaV0HoYMpnM/Y6+Oqr7AmPYy/2uEoGvS+GbSKLeRxSS1uAdu59yz0ouzcuXievSgg///WA==} + engines: {node: '>=18'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + obug@3.0.0: + resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} + engines: {node: '>=12.20.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + papaparse@5.7.0: + resolution: {integrity: sha512-qBGxg/7Q3Kl9Wfhrz2Z74UnvnHTXLNG6jmKJFeBvP2+y4lV7So+7SR62+Zd47JvdrCkX+nDcnr0ObPzek/+6RA==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + partyserver@0.5.10: + resolution: {integrity: sha512-t2B3mhTL1IOxCsj8rZgn4TxTuub7oLhypjc1/fGPNsbgnn9OsHms6uR3QEd5bFJ/7xrFo771j3DdUlll8cxgBg==} + peerDependencies: + '@cloudflare/workers-types': ^4.20260424.1 || ^5.20260703.1 + + partysocket@1.3.0: + resolution: {integrity: sha512-1zToNyolZFK/7nuAw/K2bZrNzFqaZyRoCEkS+9vG6WSC5ikrN6qWRe96q6ImU51uptz2r+dAwSkwhJVdQi4LiA==} + peerDependencies: + react: '>=17' + peerDependenciesMeta: + react: + optional: true + + path-expression-matcher@1.6.2: + resolution: {integrity: sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==} + engines: {node: '>=14.0.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postal-mime@2.7.6: + resolution: {integrity: sha512-UUlyE2KlxmvwMGq060onF/VWU3zD6dVW31FwokQ5v26jWd35fbs2MoTFzh+jXnPwAyV2MULMKXcBInGOl5TO6Q==} + + postcss@8.5.31: + resolution: {integrity: sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==} + engines: {node: ^10 || ^12 || >=14} + + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. + hasBin: true + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + proxy-addr@2.0.8: + resolution: {integrity: sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==} + engines: {node: '>= 0.10'} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + qs@6.16.1: + resolution: {integrity: sha512-5Px6J7rfHBAGUhNQ3es4YzcOdBBw0SDcVtThJml4RdnKw4tKs2epA0kPZ+K8X+WiHktT93RHVcQ/3ym5aTCgtg==} + engines: {node: '>=0.6'} + + range-parser@1.3.0: + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + re2js@1.3.3: + resolution: {integrity: sha512-s/I5zEAo79SUK0Qw4dpZKpiMwbQ6Gz0KU2NRr7eaO4x/p2g7Vvmn3hdeXDg8VsaUjfj/ora+e9oi27LX/C9+mw==} + + react@19.3.1: + resolution: {integrity: sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==} + engines: {node: '>=0.10.0'} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readable-stream@4.8.0: + resolution: {integrity: sha512-2jhTTU3Eilp/2DMT71gbcoqC35eQHasMJH0RHkYxwlxIv3+FR6Y5xAFZIwEGLxKkjZYEFlsiMNIdwUqjK2lLHQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remend@1.4.0: + resolution: {integrity: sha512-mHiYhhwphs1IgIZmkToKLwJn0U99IjPXuutkA2acrNcG0vlEq2G4TGnd2eT0saIHwh2KjaCpvleHcsd5SAz96A==} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + rolldown@1.2.14: + resolution: {integrity: sha512-eTBTTqMR6uHKLgcUqpJP8ntzDI6V4LYA8negAMBEI7gkgVvOdrx6VsvS2Ym+83KhOPdLCHWJu0w7UQFJZhHKNw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rollup@4.64.12: + resolution: {integrity: sha512-GhAu8ZglZ61VWSX/ZW3K/qkazgURBIQL0/Yy51QsS8DPyebR5Cf/Z2PANJFpTU0aVZ9byJcyqR6xvBbkXhdGYQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + run@2.1.3: + resolution: {integrity: sha512-KUurW05zgjtZ2su0cBURC1q2RG/Uq0uzV3qURDsXqiKh03p9IXABQK4Qem56cFMqjT8TdQ2iTWsePrMprQWIRA==} + engines: {node: '>=20.19.0'} + peerDependencies: + typescript: '>=5.1.6 <7' + peerDependenciesMeta: + typescript: + optional: true + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + seek-bzip@2.0.0: + resolution: {integrity: sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==} + hasBin: true + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + + sharp@0.35.5: + resolution: {integrity: sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==} + engines: {node: '>=20.9.0'} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + smol-toml@1.9.0: + resolution: {integrity: sha512-hpd+HLON7HdZXqYchMM/+LaTTbdK0AU3NngIJ4KVyWbY9bfQqdL9cD+4yf6dUoU2Ap4VsU0JkQi6FxAI1B2mXQ==} + engines: {node: '>= 18'} + + source-map-js@1.2.2: + resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + sql.js@1.15.1: + resolution: {integrity: sha512-i0M/6s+lcl67Flm/1m8/AeVU5caDramlILXU/udUwpTQym2qKMSe2sJiXB5d5WXFB272aj4B2v1JbtQ93ID3Pg==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string-width@8.3.0: + resolution: {integrity: sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==} + engines: {node: '>=20'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strnum@2.5.1: + resolution: {integrity: sha512-UM4nTLWzQiDBseVxUGxN0wJzIk0UU89Qi7pKXz9qISo+lhviJikTuikBsK/oFRlpvYHvSdz0TVoLyQ+sEpYwxA==} + + strtok3@10.6.2: + resolution: {integrity: sha512-BkdixFFUt7r7LsX6aGNPVyYMLjW+M1USLlKPNbZsrZEmLFh5tGqhdfckKo6xgsZIJqdDD0CZGkeCJJwNWQIKQA==} + engines: {node: '>=18'} + + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + + tar-fs@2.1.5: + resolution: {integrity: sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + token-types@6.1.2: + resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} + engines: {node: '>=14.16'} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + turndown@7.2.4: + resolution: {integrity: sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==} + engines: {node: '>=18', npm: '>=9'} + + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uint8array-extras@1.6.0: + resolution: {integrity: sha512-8iAasVS4wUx0gPLjH8Xtz2PeDzTSiy8QiLGu2DT3X5GU+egFEQhpnbtkehbAwjvDcxIERmCYcysiODFmE3Ud0Q==} + engines: {node: '>=18'} + + undici@7.29.1: + resolution: {integrity: sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==} + engines: {node: '>=20.18.1'} + + unenv@2.0.0-rc.24: + resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.3.4: + resolution: {integrity: sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + verkit@0.5.0: + resolution: {integrity: sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==} + engines: {node: '>=18.12.0'} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@7.3.5: + resolution: {integrity: sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + which-typed-array@1.1.24: + resolution: {integrity: sha512-wk4Mf4pR5mRP7eYuuTBCIQ9d0ud2Fv2jRLQpfgnRjbOxAFHmjKFValgTpitVKzJJS8ajnYQV2Du1SZ8j6b/EUQ==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + workerd@1.20260714.1: + resolution: {integrity: sha512-oIbQzfdyl9UQUnG6XLegcSq0Mgt/7WKDbFOoqGgOWCS+/fhyGB460uKEgdAQQ9RHCO/ttcNCX/KiMIQzdoeu3Q==} + engines: {node: '>=16'} + hasBin: true + + workers-ai-provider@3.3.1: + resolution: {integrity: sha512-vArwnmiAxQQF1clsXJd9ADn1xK9YUZVxE4umaMhrdsxM2kucxP430LfaoH4rn0AfoqtnuH3bfRhW1ak0r1x/8A==} + peerDependencies: + '@ai-sdk/anthropic': ^3.0.0 + '@ai-sdk/google': ^3.0.0 + '@ai-sdk/openai': ^3.0.0 + '@ai-sdk/provider': ^3.0.0 + ai: ^6.0.0 + peerDependenciesMeta: + '@ai-sdk/anthropic': + optional: true + '@ai-sdk/google': + optional: true + '@ai-sdk/openai': + optional: true + + workers-ai-provider@4.0.0: + resolution: {integrity: sha512-FkhwMP1EP/MKXR8Jv1o7wLVKfTqu0h/PUaEmhZ7gyDiioib5Wsh3oPAKhG+7+SWfU3roTDHaEWlJpkJjpXu+fQ==} + peerDependencies: + '@ai-sdk/anthropic': ^4.0.0 + '@ai-sdk/google': ^4.0.0 + '@ai-sdk/openai': ^4.0.0 + '@ai-sdk/provider': ^4.0.0 + ai: ^7.0.0 + peerDependenciesMeta: + '@ai-sdk/anthropic': + optional: true + '@ai-sdk/google': + optional: true + '@ai-sdk/openai': + optional: true + + wrangler@4.112.0: + resolution: {integrity: sha512-5H+XUD0TySCv1LuktFHDIEOkboH2nTfQs+35L+USt3MtntjDTMVIJprLgQcL2WBjulOyjxpd1vyTiSTJVW5MjQ==} + engines: {node: '>=22.0.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^5.20260714.1 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-naming@0.3.0: + resolution: {integrity: sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==} + engines: {node: '>=16.0.0'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaml@2.9.1: + resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@18.2.0: + resolution: {integrity: sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + youch-core@0.3.3: + resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} + + youch@4.1.0-beta.10: + resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} + + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: ^3.25.28 || ^4 + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@ai-sdk/anthropic@3.0.134(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 3.0.19 + '@ai-sdk/provider-utils': 4.0.61(zod@4.3.6) + zod: 4.3.6 + + '@ai-sdk/anthropic@4.0.84(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 4.0.31 + '@ai-sdk/provider-utils': 5.0.64(zod@4.3.6) + zod: 4.3.6 + + '@ai-sdk/gateway@3.0.128(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 3.0.10 + '@ai-sdk/provider-utils': 4.0.28(zod@4.3.6) + '@vercel/oidc': 3.2.0 + zod: 4.3.6 + + '@ai-sdk/openai@3.0.80(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 3.0.13 + '@ai-sdk/provider-utils': 4.0.35(zod@4.3.6) + zod: 4.3.6 + + '@ai-sdk/openai@4.0.98(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 4.0.31 + '@ai-sdk/provider-utils': 5.0.64(zod@4.3.6) + zod: 4.3.6 + + '@ai-sdk/provider-utils@4.0.28(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 3.0.10 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.1.1 + zod: 4.3.6 + + '@ai-sdk/provider-utils@4.0.35(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 3.0.13 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.1.1 + zod: 4.3.6 + + '@ai-sdk/provider-utils@4.0.61(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 3.0.19 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.1.1 + undici: 7.29.1 + zod: 4.3.6 + + '@ai-sdk/provider-utils@5.0.64(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 4.0.31 + '@standard-schema/spec': 1.1.0 + '@workflow/serde': 4.1.0 + eventsource-parser: 3.1.1 + undici: 7.29.1 + zod: 4.3.6 + + '@ai-sdk/provider@3.0.10': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/provider@3.0.13': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/provider@3.0.19': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/provider@4.0.31': + dependencies: + json-schema: 0.4.0 + + '@babel/code-frame@8.0.6': + dependencies: + '@babel/helper-validator-identifier': 8.0.6 + js-tokens: 10.0.0 + + '@babel/compat-data@8.0.5': {} + + '@babel/core@8.0.7': + dependencies: + '@babel/code-frame': 8.0.6 + '@babel/generator': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 + '@babel/helpers': 8.0.7 + '@babel/parser': 8.0.7 + '@babel/template': 8.0.0 + '@babel/traverse': 8.0.7 + '@babel/types': 8.0.6 + '@types/gensync': 1.0.5 + convert-source-map: 2.0.0 + empathic: 2.1.0 + gensync: 1.0.0-beta.2 + import-meta-resolve: 4.2.0 + json5: 2.2.3 + obug: 3.0.0 + verkit: 0.5.0 + + '@babel/generator@8.0.6': + dependencies: + '@babel/parser': 8.0.7 + '@babel/types': 8.0.6 + '@jridgewell/gen-mapping': 0.4.0-beta.0 + '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@8.0.0': + dependencies: + '@babel/types': 8.0.6 + + '@babel/helper-compilation-targets@8.0.7': + dependencies: + '@babel/compat-data': 8.0.5 + '@babel/helper-validator-option': 8.0.0 + browserslist: 4.29.4 + flru: 1.0.2 + verkit: 0.5.0 + + '@babel/helper-create-class-features-plugin@8.0.7(@babel/core@8.0.7)': + dependencies: + '@babel/core': 8.0.7 + '@babel/helper-annotate-as-pure': 8.0.0 + '@babel/helper-member-expression-to-functions': 8.0.5 + '@babel/helper-optimise-call-expression': 8.0.0 + '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.7) + '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 + '@babel/traverse': 8.0.7 + verkit: 0.5.0 + + '@babel/helper-globals@8.0.6': {} + + '@babel/helper-member-expression-to-functions@8.0.5': + dependencies: + '@babel/traverse': 8.0.7 + '@babel/types': 8.0.6 + + '@babel/helper-optimise-call-expression@8.0.0': + dependencies: + '@babel/types': 8.0.6 + + '@babel/helper-plugin-utils@8.0.1(@babel/core@8.0.7)': + dependencies: + '@babel/core': 8.0.7 + + '@babel/helper-replace-supers@8.0.1(@babel/core@8.0.7)': + dependencies: + '@babel/core': 8.0.7 + '@babel/helper-member-expression-to-functions': 8.0.5 + '@babel/helper-optimise-call-expression': 8.0.0 + '@babel/traverse': 8.0.7 + + '@babel/helper-skip-transparent-expression-wrappers@8.0.0': + dependencies: + '@babel/traverse': 8.0.7 + '@babel/types': 8.0.6 + + '@babel/helper-string-parser@8.0.6': {} + + '@babel/helper-validator-identifier@8.0.6': {} + + '@babel/helper-validator-option@8.0.0': {} + + '@babel/helpers@8.0.7': + dependencies: + '@babel/template': 8.0.0 + '@babel/types': 8.0.6 + + '@babel/parser@8.0.7': + dependencies: + '@babel/types': 8.0.6 + + '@babel/plugin-proposal-decorators@8.0.2(@babel/core@8.0.7)': + dependencies: + '@babel/core': 8.0.7 + '@babel/helper-create-class-features-plugin': 8.0.7(@babel/core@8.0.7) + '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) + '@babel/plugin-syntax-decorators': 8.0.1(@babel/core@8.0.7) + + '@babel/plugin-syntax-decorators@8.0.1(@babel/core@8.0.7)': + dependencies: + '@babel/core': 8.0.7 + '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) + + '@babel/runtime-corejs3@7.29.10': + dependencies: + core-js-pure: 3.51.0 + + '@babel/runtime@7.29.10': {} + + '@babel/template@8.0.0': + dependencies: + '@babel/code-frame': 8.0.6 + '@babel/parser': 8.0.7 + '@babel/types': 8.0.6 + + '@babel/traverse@8.0.7': + dependencies: + '@babel/code-frame': 8.0.6 + '@babel/generator': 8.0.6 + '@babel/helper-globals': 8.0.6 + '@babel/parser': 8.0.7 + '@babel/template': 8.0.0 + '@babel/types': 8.0.6 + obug: 3.0.0 + + '@babel/types@8.0.6': + dependencies: + '@babel/helper-string-parser': 8.0.6 + '@babel/helper-validator-identifier': 8.0.6 + + '@borewit/text-codec@0.2.2': {} + + '@cfworker/json-schema@4.1.1': {} + + '@chat-adapter/catalog@4.43.0': {} + + '@cloudflare/codemode@0.4.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6)': + dependencies: + '@types/json-schema': 7.0.15 + acorn: 8.19.0 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + zod: 4.3.6 + + '@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6)': + dependencies: + '@types/json-schema': 7.0.15 + acorn: 8.19.0 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + zod: 4.3.6 + + '@cloudflare/kv-asset-handler@0.5.0': {} + + '@cloudflare/shell@0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6)': + dependencies: + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + isomorphic-git: 1.44.3 + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - ai + - zod + + '@cloudflare/think@0.13.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 3.0.134(zod@4.3.6) + '@ai-sdk/openai': 3.0.80(zod@4.3.6) + '@cloudflare/codemode': 0.4.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + aywson: 0.0.16 + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + create-think: 0.1.1 + just-bash: 3.6.0 + smol-toml: 1.9.0 + workers-ai-provider: 3.3.1(@ai-sdk/anthropic@3.0.134(zod@4.3.6))(@ai-sdk/openai@3.0.80(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) + yargs: 18.2.0 + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.14.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 3.0.134(zod@4.3.6) + '@ai-sdk/openai': 3.0.80(zod@4.3.6) + '@cloudflare/codemode': 0.4.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + aywson: 0.0.16 + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + create-think: 0.1.1 + just-bash: 3.6.0 + smol-toml: 1.9.0 + workers-ai-provider: 3.3.1(@ai-sdk/anthropic@3.0.134(zod@4.3.6))(@ai-sdk/openai@3.0.80(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) + yargs: 18.2.0 + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.15.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.98(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + aywson: 0.0.16 + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + create-think: 0.1.1 + just-bash: 3.6.0 + smol-toml: 1.9.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) + yargs: 18.2.0 + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.15.1(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.98(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + aywson: 0.0.16 + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + create-think: 0.1.1 + just-bash: 3.6.0 + smol-toml: 1.9.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) + yargs: 18.2.0 + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.16.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.98(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.17.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.98(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.18.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.98(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.19.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.98(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/unenv-preset@2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260714.1)': + dependencies: + unenv: 2.0.0-rc.24 + optionalDependencies: + workerd: 1.20260714.1 + + '@cloudflare/vite-plugin@1.45.1(vite@7.3.5(yaml@2.9.1))(wrangler@4.112.0(@cloudflare/workers-types@5.20261019.1))': + dependencies: + '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260714.1) + miniflare: 4.20260714.0 + unenv: 2.0.0-rc.24 + vite: 7.3.5(yaml@2.9.1) + workerd: 1.20260714.1 + wrangler: 4.112.0(@cloudflare/workers-types@5.20261019.1) + ws: 8.21.0 + transitivePeerDependencies: + - '@types/node' + - bufferutil + - utf-8-validate + + '@cloudflare/workerd-darwin-64@1.20260714.1': + optional: true + + '@cloudflare/workerd-darwin-arm64@1.20260714.1': + optional: true + + '@cloudflare/workerd-linux-64@1.20260714.1': + optional: true + + '@cloudflare/workerd-linux-arm64@1.20260714.1': + optional: true + + '@cloudflare/workerd-windows-64@1.20260714.1': + optional: true + + '@cloudflare/workers-types@5.20261019.1': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@emnapi/runtime@1.11.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.28.1': + optional: true + + '@esbuild/aix-ppc64@0.28.2': + optional: true + + '@esbuild/android-arm64@0.28.1': + optional: true + + '@esbuild/android-arm64@0.28.2': + optional: true + + '@esbuild/android-arm@0.28.1': + optional: true + + '@esbuild/android-arm@0.28.2': + optional: true + + '@esbuild/android-x64@0.28.1': + optional: true + + '@esbuild/android-x64@0.28.2': + optional: true + + '@esbuild/darwin-arm64@0.28.1': + optional: true + + '@esbuild/darwin-arm64@0.28.2': + optional: true + + '@esbuild/darwin-x64@0.28.1': + optional: true + + '@esbuild/darwin-x64@0.28.2': + optional: true + + '@esbuild/freebsd-arm64@0.28.1': + optional: true + + '@esbuild/freebsd-arm64@0.28.2': + optional: true + + '@esbuild/freebsd-x64@0.28.1': + optional: true + + '@esbuild/freebsd-x64@0.28.2': + optional: true + + '@esbuild/linux-arm64@0.28.1': + optional: true + + '@esbuild/linux-arm64@0.28.2': + optional: true + + '@esbuild/linux-arm@0.28.1': + optional: true + + '@esbuild/linux-arm@0.28.2': + optional: true + + '@esbuild/linux-ia32@0.28.1': + optional: true + + '@esbuild/linux-ia32@0.28.2': + optional: true + + '@esbuild/linux-loong64@0.28.1': + optional: true + + '@esbuild/linux-loong64@0.28.2': + optional: true + + '@esbuild/linux-mips64el@0.28.1': + optional: true + + '@esbuild/linux-mips64el@0.28.2': + optional: true + + '@esbuild/linux-ppc64@0.28.1': + optional: true + + '@esbuild/linux-ppc64@0.28.2': + optional: true + + '@esbuild/linux-riscv64@0.28.1': + optional: true + + '@esbuild/linux-riscv64@0.28.2': + optional: true + + '@esbuild/linux-s390x@0.28.1': + optional: true + + '@esbuild/linux-s390x@0.28.2': + optional: true + + '@esbuild/linux-x64@0.28.1': + optional: true + + '@esbuild/linux-x64@0.28.2': + optional: true + + '@esbuild/netbsd-arm64@0.28.1': + optional: true + + '@esbuild/netbsd-arm64@0.28.2': + optional: true + + '@esbuild/netbsd-x64@0.28.1': + optional: true + + '@esbuild/netbsd-x64@0.28.2': + optional: true + + '@esbuild/openbsd-arm64@0.28.1': + optional: true + + '@esbuild/openbsd-arm64@0.28.2': + optional: true + + '@esbuild/openbsd-x64@0.28.1': + optional: true + + '@esbuild/openbsd-x64@0.28.2': + optional: true + + '@esbuild/openharmony-arm64@0.28.1': + optional: true + + '@esbuild/openharmony-arm64@0.28.2': + optional: true + + '@esbuild/sunos-x64@0.28.1': + optional: true + + '@esbuild/sunos-x64@0.28.2': + optional: true + + '@esbuild/win32-arm64@0.28.1': + optional: true + + '@esbuild/win32-arm64@0.28.2': + optional: true + + '@esbuild/win32-ia32@0.28.1': + optional: true + + '@esbuild/win32-ia32@0.28.2': + optional: true + + '@esbuild/win32-x64@0.28.1': + optional: true + + '@esbuild/win32-x64@0.28.2': + optional: true + + '@hono/node-server@2.1.5(hono@4.13.7)': + dependencies: + hono: 4.13.7 + + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.3.4 + optional: true + + '@img/sharp-darwin-x64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.3.4 + optional: true + + '@img/sharp-freebsd-wasm32@0.35.5': + dependencies: + '@img/sharp-wasm32': 0.35.5 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.3.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.3.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.3.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.3.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.3.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.3.4': + optional: true + + '@img/sharp-linux-arm64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.3.4 + optional: true + + '@img/sharp-linux-arm@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.3.4 + optional: true + + '@img/sharp-linux-ppc64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.3.4 + optional: true + + '@img/sharp-linux-riscv64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.3.4 + optional: true + + '@img/sharp-linux-s390x@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.3.4 + optional: true + + '@img/sharp-linux-x64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.3.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.3.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.3.4 + optional: true + + '@img/sharp-wasm32@0.35.5': + dependencies: + '@emnapi/runtime': 1.11.3 + optional: true + + '@img/sharp-webcontainers-wasm32@0.35.5': + dependencies: + '@img/sharp-wasm32': 0.35.5 + optional: true + + '@img/sharp-win32-arm64@0.35.5': + optional: true + + '@img/sharp-win32-ia32@0.35.5': + optional: true + + '@img/sharp-win32-x64@0.35.5': + optional: true + + '@jridgewell/gen-mapping@0.4.0-beta.0': + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.6.0': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@mixmark-io/domino@2.2.0': {} + + '@modelcontextprotocol/client@2.0.0': + dependencies: + '@modelcontextprotocol/core': 2.0.0 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.1.1 + jose: 6.2.13 + pkce-challenge: 5.0.1 + zod: 4.3.6 + + '@modelcontextprotocol/core@2.0.0': + dependencies: + zod: 4.3.6 + + '@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6)': + dependencies: + '@hono/node-server': 2.1.5(hono@4.13.7) + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.1.1 + express: 5.3.0 + express-rate-limit: 8.7.1(express@5.3.0) + hono: 4.13.7 + jose: 6.2.13 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.3.6 + zod-to-json-schema: 3.25.2(zod@4.3.6) + optionalDependencies: + '@cfworker/json-schema': 4.1.1 + transitivePeerDependencies: + - supports-color + + '@modelcontextprotocol/server@2.0.0': + dependencies: + '@modelcontextprotocol/core': 2.0.0 + zod: 4.3.6 + + '@mongodb-js/zstd@7.0.0': + dependencies: + node-addon-api: 8.9.2 + prebuild-install: 7.1.3 + optional: true + + '@napi-rs/lzma-linux-x64-gnu@1.5.1': + optional: true + + '@nodable/entities@3.1.0': {} + + '@opentelemetry/api@1.9.1': {} + + '@oxc-project/types@0.154.0': {} + + '@poppinss/colors@4.1.6': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.6.5': + dependencies: + '@poppinss/colors': 4.1.6 + '@sindresorhus/is': 7.2.0 + supports-color: 10.2.2 + + '@poppinss/exception@1.2.3': {} + + '@rolldown/binding-android-arm-eabi@1.2.14': + optional: true + + '@rolldown/binding-android-arm64@1.2.14': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.14': + optional: true + + '@rolldown/binding-darwin-x64@1.2.14': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.14': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.14': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.14': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.14': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.14': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.14': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.14': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.14': + optional: true + + '@rolldown/binding-openharmony-arm64@1.2.14': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.14': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.14': + optional: true + + '@rolldown/plugin-babel@0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))': + dependencies: + '@babel/core': 8.0.7 + picomatch: 4.0.7 + rolldown: 1.2.14 + optionalDependencies: + '@babel/runtime': 7.29.10 + vite: 7.3.5(yaml@2.9.1) + + '@rolldown/pluginutils@1.0.1': {} + + '@rollup/rollup-android-arm-eabi@4.64.12': + optional: true + + '@rollup/rollup-android-arm64@4.64.12': + optional: true + + '@rollup/rollup-darwin-arm64@4.64.12': + optional: true + + '@rollup/rollup-darwin-x64@4.64.12': + optional: true + + '@rollup/rollup-freebsd-arm64@4.64.12': + optional: true + + '@rollup/rollup-freebsd-x64@4.64.12': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.64.12': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.64.12': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.64.12': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.64.12': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.64.12': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.64.12': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-x64-musl@4.64.12': + optional: true + + '@rollup/rollup-openbsd-x64@4.64.12': + optional: true + + '@rollup/rollup-openharmony-arm64@4.64.12': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.64.12': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.64.12': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.64.12': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.64.12': + optional: true + + '@sindresorhus/is@7.2.0': {} + + '@speed-highlight/core@1.2.24': {} + + '@standard-schema/spec@1.1.0': {} + + '@tokenizer/inflate@0.4.1': + dependencies: + debug: 4.4.3 + token-types: 6.1.2 + transitivePeerDependencies: + - supports-color + + '@tokenizer/token@0.3.0': {} + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree@1.0.9': {} + + '@types/gensync@1.0.5': {} + + '@types/jsesc@2.5.1': {} + + '@types/json-schema@7.0.15': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/ms@2.1.0': {} + + '@types/unist@3.0.3': {} + + '@vercel/oidc@3.2.0': {} + + '@workflow/serde@4.1.0': {} + + '@workflow/serde@4.1.0-beta.2': {} + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.1.0 + + acorn@8.19.0: {} + + agents@0.17.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/workers-types@5.20261019.1)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): + dependencies: + '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) + '@cfworker/json-schema': 4.1.1 + '@cloudflare/codemode': 0.4.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + '@rolldown/plugin-babel': 0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1)) + cron-schedule: 6.0.0 + esbuild: 0.28.2 + mimetext: 3.0.28 + nanoid: 5.1.16 + partyserver: 0.5.10(@cloudflare/workers-types@5.20261019.1) + partysocket: 1.3.0(react@19.3.1) + react: 19.3.1 + yaml: 2.9.1 + yargs: 18.2.0 + zod: 4.3.6 + optionalDependencies: + ai: 6.0.202(zod@4.3.6) + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@babel/core' + - '@babel/plugin-transform-runtime' + - '@babel/runtime' + - '@cloudflare/workers-types' + - rolldown + - supports-color + + agents@0.18.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/workers-types@5.20261019.1)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): + dependencies: + '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) + '@cfworker/json-schema': 4.1.1 + '@cloudflare/codemode': 0.4.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + '@rolldown/plugin-babel': 0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1)) + cron-schedule: 6.0.0 + esbuild: 0.28.2 + mimetext: 3.0.28 + nanoid: 5.1.16 + partyserver: 0.5.10(@cloudflare/workers-types@5.20261019.1) + partysocket: 1.3.0(react@19.3.1) + react: 19.3.1 + yaml: 2.9.1 + yargs: 18.2.0 + zod: 4.3.6 + optionalDependencies: + ai: 6.0.202(zod@4.3.6) + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@babel/core' + - '@babel/plugin-transform-runtime' + - '@babel/runtime' + - '@cloudflare/workers-types' + - rolldown + - supports-color + + agents@0.22.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): + dependencies: + '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) + '@cfworker/json-schema': 4.1.1 + '@modelcontextprotocol/client': 2.0.0 + '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + '@modelcontextprotocol/server': 2.0.0 + '@rolldown/plugin-babel': 0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1)) + cron-schedule: 6.0.0 + esbuild: 0.28.2 + mimetext: 3.0.28 + nanoid: 5.1.16 + partysocket: 1.3.0(react@19.3.1) + yaml: 2.9.1 + zod: 4.3.6 + optionalDependencies: + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + react: 19.3.1 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@babel/core' + - '@babel/plugin-transform-runtime' + - '@babel/runtime' + - rolldown + + agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): + dependencies: + '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) + '@cfworker/json-schema': 4.1.1 + '@modelcontextprotocol/client': 2.0.0 + '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + '@modelcontextprotocol/server': 2.0.0 + '@rolldown/plugin-babel': 0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1)) + capnweb: 0.12.0 + cron-schedule: 6.0.0 + esbuild: 0.28.2 + mimetext: 3.0.28 + nanoid: 5.1.16 + partysocket: 1.3.0(react@19.3.1) + postal-mime: 2.7.6 + yaml: 2.9.1 + zod: 4.3.6 + optionalDependencies: + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + ai: 6.0.202(zod@4.3.6) + chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + react: 19.3.1 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@babel/core' + - '@babel/plugin-transform-runtime' + - '@babel/runtime' + - rolldown + + ai@6.0.202(zod@4.3.6): + dependencies: + '@ai-sdk/gateway': 3.0.128(zod@4.3.6) + '@ai-sdk/provider': 3.0.10 + '@ai-sdk/provider-utils': 4.0.28(zod@4.3.6) + '@opentelemetry/api': 1.9.1 + zod: 4.3.6 + + ajv-formats@3.0.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.8 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-regex@6.4.0: {} + + ansi-styles@6.2.3: {} + + anynum@1.0.1: {} + + async-lock@1.4.1: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + aywson@0.0.16: + dependencies: + chalk: 5.6.2 + jsonc-parser: 3.3.1 + + bail@2.0.2: {} + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.11.30: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + optional: true + + blake3-wasm@2.1.5: {} + + body-parser@2.3.0: + dependencies: + bytes: 3.1.2 + content-type: 2.1.0 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + on-finished: 2.4.1 + qs: 6.16.1 + raw-body: 3.0.2 + type-is: 2.1.0 + transitivePeerDependencies: + - supports-color + + browserslist@4.29.4: + dependencies: + baseline-browser-mapping: 2.11.30 + caniuse-lite: 1.0.30001817 + electron-to-chromium: 1.5.460 + node-releases: 2.0.59 + update-browserslist-db: 1.3.4(browserslist@4.29.4) + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + optional: true + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bytes@3.1.2: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + caniuse-lite@1.0.30001817: {} + + capnweb@0.12.0: {} + + ccount@2.0.1: {} + + chalk@5.6.2: {} + + character-entities@2.0.2: {} + + chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6): + dependencies: + '@chat-adapter/catalog': 4.43.0 + '@workflow/serde': 4.1.0-beta.2 + mdast-util-to-string: 4.0.0 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + remend: 1.4.0 + unified: 11.0.5 + optionalDependencies: + ai: 6.0.202(zod@4.3.6) + zod: 4.3.6 + transitivePeerDependencies: + - supports-color + + chownr@1.1.4: + optional: true + + clean-git-ref@2.0.1: {} + + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + + commander@6.2.1: {} + + content-disposition@2.0.1: {} + + content-type@1.0.5: {} + + content-type@2.1.0: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cookie@1.1.1: {} + + core-js-pure@3.51.0: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + crc-32@1.2.2: {} + + create-think@0.1.1: {} + + cron-schedule@6.0.0: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + dc-browser@1.0.4: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-extend@0.6.0: + optional: true + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + depd@2.0.0: {} + + dequal@2.0.3: {} + + detect-libc@2.1.2: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff3@0.0.3: {} + + diff@8.0.4: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.460: {} + + emoji-regex@10.6.0: {} + + empathic@2.1.0: {} + + encodeurl@2.0.0: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + optional: true + + error-stack-parser-es@1.0.5: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + esbuild@0.28.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 + + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@5.0.0: {} + + etag@1.8.1: {} + + event-target-polyfill@0.0.4: {} + + event-target-shim@5.0.1: {} + + events@3.3.0: {} + + eventsource-parser@3.1.1: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.1.1 + + expand-template@2.0.3: + optional: true + + express-rate-limit@8.7.1(express@5.3.0): + dependencies: + debug: 4.4.3 + express: 5.3.0 + ip-address: 10.7.1 + transitivePeerDependencies: + - supports-color + + express@5.3.0: + dependencies: + accepts: 2.0.0 + body-parser: 2.3.0 + content-disposition: 2.0.1 + content-type: 2.1.0 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.8 + qs: 6.16.1 + range-parser: 1.3.0 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.1.0 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-uri@3.1.8: {} + + fast-xml-builder@1.3.1: + dependencies: + path-expression-matcher: 1.6.2 + xml-naming: 0.3.0 + + fast-xml-parser@5.11.2: + dependencies: + '@nodable/entities': 3.1.0 + fast-xml-builder: 1.3.1 + is-unsafe: 2.0.2 + path-expression-matcher: 1.6.2 + strnum: 2.5.1 + xml-naming: 0.3.0 + + fdir@6.5.0(picomatch@4.0.7): + optionalDependencies: + picomatch: 4.0.7 + + file-type@21.3.4: + dependencies: + '@tokenizer/inflate': 0.4.1 + strtok3: 10.6.2 + token-types: 6.1.2 + uint8array-extras: 1.6.0 + transitivePeerDependencies: + - supports-color + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + flru@1.0.2: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + fs-constants@1.0.0: + optional: true + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.7.0: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + github-from-package@0.0.0: + optional: true + + gopd@1.2.0: {} + + guarded-fetch@0.1.3: + dependencies: + ipaddr.js: 2.2.0 + undici: 7.29.1 + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + hono@4.13.7: {} + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + iconv-lite@0.7.3: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + import-meta-resolve@4.2.0: {} + + inherits@2.0.4: {} + + ini@1.3.8: + optional: true + + ini@6.0.0: {} + + ip-address@10.7.1: {} + + ipaddr.js@1.9.1: {} + + ipaddr.js@2.2.0: {} + + is-callable@1.2.7: {} + + is-plain-obj@4.1.0: {} + + is-promise@4.0.0: {} + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.24 + + is-unsafe@2.0.2: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isomorphic-git@1.44.3: + dependencies: + async-lock: 1.4.1 + clean-git-ref: 2.0.1 + crc-32: 1.2.2 + diff3: 0.0.3 + ignore: 5.3.2 + minimisted: 2.0.1 + pako: 1.0.11 + pify: 4.0.1 + readable-stream: 4.8.0 + sha.js: 2.4.12 + simple-get: 4.0.1 + + jose@6.2.13: {} + + js-base64@3.9.4: {} + + js-tokens@10.0.0: {} + + jsesc@3.1.0: {} + + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + + json-schema@0.4.0: {} + + json5@2.2.3: {} + + jsonc-parser@3.3.1: {} + + just-bash@3.6.0: + dependencies: + diff: 8.0.4 + fast-xml-parser: 5.11.2 + file-type: 21.3.4 + guarded-fetch: 0.1.3 + ini: 6.0.0 + modern-tar: 0.7.7 + papaparse: 5.7.0 + re2js: 1.3.3 + run: 2.1.3(typescript@5.9.3) + seek-bzip: 2.0.0 + smol-toml: 1.9.0 + sprintf-js: 1.1.3 + sql.js: 1.15.1 + turndown: 7.2.4 + typescript: 5.9.3 + yaml: 2.9.1 + optionalDependencies: + '@mongodb-js/zstd': 7.0.0 + node-liblzma: 2.2.0 + transitivePeerDependencies: + - supports-color + + kleur@4.1.5: {} + + longest-streak@3.1.0: {} + + markdown-table@3.0.4: {} + + math-intrinsics@1.1.0: {} + + mdast-util-find-and-replace@3.0.3: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.3 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.3 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.1.0 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.1 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-markdown@2.2.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-character: 2.1.1 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + media-typer@1.1.1: {} + + merge-descriptors@2.0.0: {} + + micromark-core-commonmark@2.0.4: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.1.0 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-edit-map: 1.0.0 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.4 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-table@2.1.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.3 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.2 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-space@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.3 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-edit-map@1.0.0: + dependencies: + micromark-util-types: 2.0.3 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.3 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.3: {} + + micromark@4.0.3: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.4 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-edit-map: 1.0.0 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + transitivePeerDependencies: + - supports-color + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mimetext@3.0.28: + dependencies: + '@babel/runtime': 7.29.10 + '@babel/runtime-corejs3': 7.29.10 + js-base64: 3.9.4 + mime-types: 2.1.35 + + mimic-response@3.1.0: {} + + miniflare@4.20260714.0: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + sharp: 0.35.5 + undici: 7.29.1 + workerd: 1.20260714.1 + ws: 8.21.0 + youch: 4.1.0-beta.10 + transitivePeerDependencies: + - '@types/node' + - bufferutil + - utf-8-validate + + minimist@1.2.8: {} + + minimisted@2.0.1: + dependencies: + minimist: 1.2.8 + + mkdirp-classic@0.5.3: + optional: true + + modern-tar@0.7.7: {} + + ms@2.1.3: {} + + nanoid@3.3.20: {} + + nanoid@5.1.16: {} + + napi-build-utils@2.0.0: + optional: true + + negotiator@1.1.0: + dependencies: + content-type: 2.1.0 + + node-abi@3.99.0: + dependencies: + semver: 7.8.5 + optional: true + + node-addon-api@8.9.2: + optional: true + + node-gyp-build@4.8.4: + optional: true + + node-liblzma@2.2.0: + dependencies: + node-addon-api: 8.9.2 + node-gyp-build: 4.8.4 + optional: true + + node-releases@2.0.59: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + obug@3.0.0: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + pako@1.0.11: {} + + papaparse@5.7.0: {} + + parseurl@1.3.3: {} + + partyserver@0.5.10(@cloudflare/workers-types@5.20261019.1): + dependencies: + '@cloudflare/workers-types': 5.20261019.1 + nanoid: 5.1.16 + + partysocket@1.3.0(react@19.3.1): + dependencies: + event-target-polyfill: 0.0.4 + optionalDependencies: + react: 19.3.1 + + path-expression-matcher@1.6.2: {} + + path-key@3.1.1: {} + + path-to-regexp@6.3.0: {} + + path-to-regexp@8.4.2: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.7: {} + + pify@4.0.1: {} + + pkce-challenge@5.0.1: {} + + possible-typed-array-names@1.1.0: {} + + postal-mime@2.7.6: {} + + postcss@8.5.31: + dependencies: + nanoid: 3.3.20 + picocolors: 1.1.1 + source-map-js: 1.2.2 + + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.99.0 + pump: 3.0.4 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.5 + tunnel-agent: 0.6.0 + optional: true + + process@0.11.10: {} + + proxy-addr@2.0.8: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + optional: true + + qs@6.16.1: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + + range-parser@1.3.0: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + unpipe: 1.0.0 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + optional: true + + re2js@1.3.3: {} + + react@19.3.1: {} + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + optional: true + + readable-stream@4.8.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.1.0 + micromark-util-types: 2.0.3 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.2.0 + unified: 11.0.5 + + remend@1.4.0: {} + + require-from-string@2.0.2: {} + + rolldown@1.2.14: + dependencies: + '@oxc-project/types': 0.154.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm-eabi': 1.2.14 + '@rolldown/binding-android-arm64': 1.2.14 + '@rolldown/binding-darwin-arm64': 1.2.14 + '@rolldown/binding-darwin-x64': 1.2.14 + '@rolldown/binding-freebsd-x64': 1.2.14 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.14 + '@rolldown/binding-linux-arm64-gnu': 1.2.14 + '@rolldown/binding-linux-arm64-musl': 1.2.14 + '@rolldown/binding-linux-ppc64-gnu': 1.2.14 + '@rolldown/binding-linux-s390x-gnu': 1.2.14 + '@rolldown/binding-linux-x64-gnu': 1.2.14 + '@rolldown/binding-linux-x64-musl': 1.2.14 + '@rolldown/binding-openharmony-arm64': 1.2.14 + '@rolldown/binding-win32-arm64-msvc': 1.2.14 + '@rolldown/binding-win32-x64-msvc': 1.2.14 + + rollup@4.64.12: + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + '@napi-rs/lzma-linux-x64-gnu': 1.5.1 + '@rollup/rollup-android-arm-eabi': 4.64.12 + '@rollup/rollup-android-arm64': 4.64.12 + '@rollup/rollup-darwin-arm64': 4.64.12 + '@rollup/rollup-darwin-x64': 4.64.12 + '@rollup/rollup-freebsd-arm64': 4.64.12 + '@rollup/rollup-freebsd-x64': 4.64.12 + '@rollup/rollup-linux-arm-gnueabihf': 4.64.12 + '@rollup/rollup-linux-arm-musleabihf': 4.64.12 + '@rollup/rollup-linux-arm64-gnu': 4.64.12 + '@rollup/rollup-linux-arm64-musl': 4.64.12 + '@rollup/rollup-linux-loong64-gnu': 4.64.12 + '@rollup/rollup-linux-loong64-musl': 4.64.12 + '@rollup/rollup-linux-ppc64-gnu': 4.64.12 + '@rollup/rollup-linux-ppc64-musl': 4.64.12 + '@rollup/rollup-linux-riscv64-gnu': 4.64.12 + '@rollup/rollup-linux-riscv64-musl': 4.64.12 + '@rollup/rollup-linux-s390x-gnu': 4.64.12 + '@rollup/rollup-linux-x64-gnu': 4.64.12 + '@rollup/rollup-linux-x64-musl': 4.64.12 + '@rollup/rollup-openbsd-x64': 4.64.12 + '@rollup/rollup-openharmony-arm64': 4.64.12 + '@rollup/rollup-win32-arm64-msvc': 4.64.12 + '@rollup/rollup-win32-ia32-msvc': 4.64.12 + '@rollup/rollup-win32-x64-gnu': 4.64.12 + '@rollup/rollup-win32-x64-msvc': 4.64.12 + fsevents: 2.3.3 + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.4.2 + transitivePeerDependencies: + - supports-color + + run@2.1.3(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + seek-bzip@2.0.0: + dependencies: + commander: 6.2.1 + + semver@7.8.5: {} + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.3.0 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + sha.js@2.4.12: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + sharp@0.35.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.35.5 + '@img/sharp-darwin-x64': 0.35.5 + '@img/sharp-freebsd-wasm32': 0.35.5 + '@img/sharp-libvips-darwin-arm64': 1.3.4 + '@img/sharp-libvips-darwin-x64': 1.3.4 + '@img/sharp-libvips-linux-arm': 1.3.4 + '@img/sharp-libvips-linux-arm64': 1.3.4 + '@img/sharp-libvips-linux-ppc64': 1.3.4 + '@img/sharp-libvips-linux-riscv64': 1.3.4 + '@img/sharp-libvips-linux-s390x': 1.3.4 + '@img/sharp-libvips-linux-x64': 1.3.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.4 + '@img/sharp-libvips-linuxmusl-x64': 1.3.4 + '@img/sharp-linux-arm': 0.35.5 + '@img/sharp-linux-arm64': 0.35.5 + '@img/sharp-linux-ppc64': 0.35.5 + '@img/sharp-linux-riscv64': 0.35.5 + '@img/sharp-linux-s390x': 0.35.5 + '@img/sharp-linux-x64': 0.35.5 + '@img/sharp-linuxmusl-arm64': 0.35.5 + '@img/sharp-linuxmusl-x64': 0.35.5 + '@img/sharp-webcontainers-wasm32': 0.35.5 + '@img/sharp-win32-arm64': 0.35.5 + '@img/sharp-win32-ia32': 0.35.5 + '@img/sharp-win32-x64': 0.35.5 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + + smol-toml@1.9.0: {} + + source-map-js@1.2.2: {} + + sprintf-js@1.1.3: {} + + sql.js@1.15.1: {} + + statuses@2.0.2: {} + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.7.0 + strip-ansi: 7.2.0 + + string-width@8.3.0: + dependencies: + get-east-asian-width: 1.7.0 + strip-ansi: 7.2.0 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.4.0 + + strip-json-comments@2.0.1: + optional: true + + strnum@2.5.1: + dependencies: + anynum: 1.0.1 + + strtok3@10.6.2: + dependencies: + '@tokenizer/token': 0.3.0 + + supports-color@10.2.2: {} + + tar-fs@2.1.5: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.4 + tar-stream: 2.2.0 + optional: true + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + optional: true + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + + toidentifier@1.0.1: {} + + token-types@6.1.2: + dependencies: + '@borewit/text-codec': 0.2.2 + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + + trough@2.2.0: {} + + tslib@2.8.1: + optional: true + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + optional: true + + turndown@7.2.4: + dependencies: + '@mixmark-io/domino': 2.2.0 + + type-is@2.1.0: + dependencies: + content-type: 2.1.0 + media-typer: 1.1.1 + mime-types: 3.0.2 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typescript@5.9.3: {} + + uint8array-extras@1.6.0: {} + + undici@7.29.1: {} + + unenv@2.0.0-rc.24: + dependencies: + pathe: 2.0.3 + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + unpipe@1.0.0: {} + + update-browserslist-db@1.3.4(browserslist@4.29.4): + dependencies: + browserslist: 4.29.4 + escalade: 3.2.0 + picocolors: 1.1.1 + + util-deprecate@1.0.2: + optional: true + + vary@1.1.2: {} + + verkit@0.5.0: {} + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite@7.3.5(yaml@2.9.1): + dependencies: + esbuild: 0.28.2 + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + postcss: 8.5.31 + rollup: 4.64.12 + tinyglobby: 0.2.17 + optionalDependencies: + fsevents: 2.3.3 + yaml: 2.9.1 + + which-typed-array@1.1.24: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + workerd@1.20260714.1: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20260714.1 + '@cloudflare/workerd-darwin-arm64': 1.20260714.1 + '@cloudflare/workerd-linux-64': 1.20260714.1 + '@cloudflare/workerd-linux-arm64': 1.20260714.1 + '@cloudflare/workerd-windows-64': 1.20260714.1 + + workers-ai-provider@3.3.1(@ai-sdk/anthropic@3.0.134(zod@4.3.6))(@ai-sdk/openai@3.0.80(zod@4.3.6))(ai@6.0.202(zod@4.3.6)): + dependencies: + ai: 6.0.202(zod@4.3.6) + optionalDependencies: + '@ai-sdk/anthropic': 3.0.134(zod@4.3.6) + '@ai-sdk/openai': 3.0.80(zod@4.3.6) + + workers-ai-provider@4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)): + dependencies: + ai: 6.0.202(zod@4.3.6) + optionalDependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.98(zod@4.3.6) + + wrangler@4.112.0(@cloudflare/workers-types@5.20261019.1): + dependencies: + '@cloudflare/kv-asset-handler': 0.5.0 + '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260714.1) + blake3-wasm: 2.1.5 + esbuild: 0.28.1 + miniflare: 4.20260714.0 + path-to-regexp: 6.3.0 + unenv: 2.0.0-rc.24 + workerd: 1.20260714.1 + optionalDependencies: + '@cloudflare/workers-types': 5.20261019.1 + fsevents: 2.3.3 + transitivePeerDependencies: + - '@types/node' + - bufferutil + - utf-8-validate + + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + + wrappy@1.0.2: {} + + ws@8.21.0: {} + + xml-naming@0.3.0: {} + + y18n@5.0.8: {} + + yaml@2.9.1: {} + + yargs-parser@22.0.0: {} + + yargs@18.2.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 8.3.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + + youch-core@0.3.3: + dependencies: + '@poppinss/exception': 1.2.3 + error-stack-parser-es: 1.0.5 + + youch@4.1.0-beta.10: + dependencies: + '@poppinss/colors': 4.1.6 + '@poppinss/dumper': 0.6.5 + '@speed-highlight/core': 1.2.24 + cookie: 1.1.1 + youch-core: 0.3.3 + + zod-to-json-schema@3.25.2(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@4.3.6: {} + + zwitch@2.0.4: {} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/package.json b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/package.json new file mode 100644 index 000000000..a3ea66af5 --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/package.json @@ -0,0 +1,55 @@ +{ + "name": "@braintrust/e2e-cloudflare-think-ai7", + "private": true, + "type": "module", + "dependencies": { + "@ai-sdk/openai": "4.0.93", + "@cloudflare/vite-plugin": "1.45.1", + "agents": "0.28.0", + "ai": "7.0.138", + "ai-unwrapped": "npm:ai@7.0.138", + "dc-browser": "1.0.4", + "vite": "7.3.5", + "wrangler": "4.112.0", + "zod": "4.3.6", + "cloudflare-think-v0-15": "npm:@cloudflare/think@0.15.0", + "cloudflare-think-v0-15-latest": "npm:@cloudflare/think@0.15.1", + "cloudflare-think-v0-16": "npm:@cloudflare/think@0.16.0", + "cloudflare-think-v0-16-latest": "npm:@cloudflare/think@0.16.0", + "cloudflare-think-v0-17": "npm:@cloudflare/think@0.17.0", + "cloudflare-think-v0-17-latest": "npm:@cloudflare/think@0.17.0", + "cloudflare-think-v0-18": "npm:@cloudflare/think@0.18.0", + "cloudflare-think-v0-18-latest": "npm:@cloudflare/think@0.18.0", + "cloudflare-think-v0-19": "npm:@cloudflare/think@0.19.0", + "cloudflare-think-v0-19-latest": "npm:@cloudflare/think@0.19.0", + "cloudflare-think-v0-20": "npm:@cloudflare/think@0.20.0", + "cloudflare-think-v0-20-latest": "npm:@cloudflare/think@0.20.2", + "cloudflare-think-v0-20-1": "npm:@cloudflare/think@0.20.1", + "agents-v0-18": "npm:agents@0.18.0", + "agents-v0-22": "npm:agents@0.22.0" + }, + "pnpm": { + "overrides": { + "esbuild@<0.28.1": "^0.28.1", + "ip-address@<10.2.2": "10.7.1", + "sharp@<0.35.0": "0.35.5", + "@hono/node-server@<2.0.5": "^2.0.10", + "brace-expansion@5.0.7": "5.0.12", + "undici@<7.29.0": "7.29.1", + "hono@<4.12.34": "4.13.7", + "nanoid@<3.3.18": "^3.3.18", + "fast-uri@<3.1.5": "3.1.8", + "postcss@<8.5.23": "^8.5.23", + "fast-uri@>=3.0.0 <3.1.8": "3.1.8", + "ip-address@>=10.0.0 <10.7.1": "10.7.1", + "undici@>=7.0.0 <7.29.1": "7.29.1", + "brace-expansion@>=5.0.0 <5.0.12": "5.0.12", + "hono@>=4.0.0 <4.13.7": "4.13.7", + "proxy-addr@>=2.0.0 <2.0.8": "2.0.8", + "source-map-js@>=1.0.0 <1.2.2": "1.2.2", + "smol-toml@>=1.0.0 <1.9.0": "1.9.0", + "sharp@>=0.35.0 <0.35.5": "0.35.5", + "@modelcontextprotocol/sdk@>=1.0.0 <1.31.0": "1.31.0" + } + } +} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/pnpm-lock.yaml b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/pnpm-lock.yaml new file mode 100644 index 000000000..cb92724aa --- /dev/null +++ b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/pnpm-lock.yaml @@ -0,0 +1,5515 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + esbuild@<0.28.1: ^0.28.1 + ip-address@<10.2.2: 10.7.1 + sharp@<0.35.0: 0.35.5 + '@hono/node-server@<2.0.5': ^2.0.10 + brace-expansion@5.0.7: 5.0.12 + undici@<7.29.0: 7.29.1 + hono@<4.12.34: 4.13.7 + nanoid@<3.3.18: ^3.3.18 + fast-uri@<3.1.5: 3.1.8 + postcss@<8.5.23: ^8.5.23 + fast-uri@>=3.0.0 <3.1.8: 3.1.8 + ip-address@>=10.0.0 <10.7.1: 10.7.1 + undici@>=7.0.0 <7.29.1: 7.29.1 + brace-expansion@>=5.0.0 <5.0.12: 5.0.12 + hono@>=4.0.0 <4.13.7: 4.13.7 + proxy-addr@>=2.0.0 <2.0.8: 2.0.8 + source-map-js@>=1.0.0 <1.2.2: 1.2.2 + smol-toml@>=1.0.0 <1.9.0: 1.9.0 + sharp@>=0.35.0 <0.35.5: 0.35.5 + '@modelcontextprotocol/sdk@>=1.0.0 <1.31.0': 1.31.0 + +importers: + + .: + dependencies: + '@ai-sdk/openai': + specifier: 4.0.93 + version: 4.0.93(zod@4.3.6) + '@cloudflare/vite-plugin': + specifier: 1.45.1 + version: 1.45.1(vite@7.3.5(yaml@2.9.1))(wrangler@4.112.0(@cloudflare/workers-types@5.20261019.1)) + agents: + specifier: 0.28.0 + version: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + agents-v0-18: + specifier: npm:agents@0.18.0 + version: agents@0.18.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/workers-types@5.20261019.1)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + agents-v0-22: + specifier: npm:agents@0.22.0 + version: agents@0.22.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: + specifier: 7.0.138 + version: 7.0.138(zod@4.3.6) + ai-unwrapped: + specifier: npm:ai@7.0.138 + version: ai@7.0.138(zod@4.3.6) + cloudflare-think-v0-15: + specifier: npm:@cloudflare/think@0.15.0 + version: '@cloudflare/think@0.15.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' + cloudflare-think-v0-15-latest: + specifier: npm:@cloudflare/think@0.15.1 + version: '@cloudflare/think@0.15.1(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' + cloudflare-think-v0-16: + specifier: npm:@cloudflare/think@0.16.0 + version: '@cloudflare/think@0.16.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-16-latest: + specifier: npm:@cloudflare/think@0.16.0 + version: '@cloudflare/think@0.16.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-17: + specifier: npm:@cloudflare/think@0.17.0 + version: '@cloudflare/think@0.17.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-17-latest: + specifier: npm:@cloudflare/think@0.17.0 + version: '@cloudflare/think@0.17.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-18: + specifier: npm:@cloudflare/think@0.18.0 + version: '@cloudflare/think@0.18.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-18-latest: + specifier: npm:@cloudflare/think@0.18.0 + version: '@cloudflare/think@0.18.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-19: + specifier: npm:@cloudflare/think@0.19.0 + version: '@cloudflare/think@0.19.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-19-latest: + specifier: npm:@cloudflare/think@0.19.0 + version: '@cloudflare/think@0.19.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-20: + specifier: npm:@cloudflare/think@0.20.0 + version: '@cloudflare/think@0.20.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-20-1: + specifier: npm:@cloudflare/think@0.20.1 + version: '@cloudflare/think@0.20.1(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + cloudflare-think-v0-20-latest: + specifier: npm:@cloudflare/think@0.20.2 + version: '@cloudflare/think@0.20.2(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' + dc-browser: + specifier: 1.0.4 + version: 1.0.4 + vite: + specifier: 7.3.5 + version: 7.3.5(yaml@2.9.1) + wrangler: + specifier: 4.112.0 + version: 4.112.0(@cloudflare/workers-types@5.20261019.1) + zod: + specifier: 4.3.6 + version: 4.3.6 + +packages: + + '@ai-sdk/anthropic@4.0.84': + resolution: {integrity: sha512-jcqib3OpVtcMmJDWYpQqkjAusaLyqfORyM4bDc3UwLgP/usfiTONfj98HeQCLwMJ2uxrmSWiXFga2Rw/k50usw==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/gateway@4.0.111': + resolution: {integrity: sha512-+Uq8GgAsEkq3rv1AoYyqpCeHSOXG5ZP7KnsquM8yyIXkn1oBeZbFZvTtNE6gC9Eg1VK34KwImv8NrtB6tfm2wA==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/openai@4.0.93': + resolution: {integrity: sha512-UUTCBDWwkNvsbukMstaT31K6wYnL73vp0X4gQL1/7W3LZlHT1wOZ6eZzlwj76s/O+QLXefWF6+ceRgPwTOX6FA==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@5.0.59': + resolution: {integrity: sha512-eaXBTkguxBFzS+KvxGRsbdkX9A7+R1g/C4jWx9mup0oSs3Cx5Mb427/byGpD2XL8SnMYT9O8LmXBmrgo+N3TJw==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@5.0.64': + resolution: {integrity: sha512-BDU8rDR6mBR+na5U/Dj4B33LX980x200lqhBGRIOxxx1NFunoixuvvweqIB+sCsCoFC8cGCsa82Ce2fKoAPOqw==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider@4.0.27': + resolution: {integrity: sha512-TtWwm6SxFiPomlMIbTQa+yhJte+w4/oCsW+wJrJzMC3MqHpAY9e5dJF1Y4HxyKt3W2Csac0KiI76Ckio11TFYw==} + engines: {node: '>=22'} + + '@ai-sdk/provider@4.0.31': + resolution: {integrity: sha512-3wJnwVTFg8SwOyoZCv+ov7Re2GB+7IQnU5a5MYJACrtiWDDUHgqTBeeesq2MB2ddgojzL8hgWleltwpAgtUqfg==} + engines: {node: '>=22'} + + '@babel/code-frame@8.0.6': + resolution: {integrity: sha512-uMHhvmDmwFiLuiozaoRYTZHqMFuu3fem/X9JY78lohAuLoh8LSGGC8JqUzo2cVuBsBxkjMZNk56CE7ock8Xxkw==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/compat-data@8.0.5': + resolution: {integrity: sha512-YLsYoQMvL8l8WrGpN3Zj7O1wK5LEBN+cQtux7BcuHyxIXve724XG+zuJ1n3U1cUweRtTzQOA4IHbuQw3N34SZw==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/core@8.0.7': + resolution: {integrity: sha512-ZIsZWBG6Y1oa+8fkQVp0xeCdjCHBkXFCCIWrmg9SvejVvfcVQgKKRmGrBDWfM7rilhvnRoEuaqa5dkK7KB3pHA==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/generator@8.0.6': + resolution: {integrity: sha512-/pcanjdRsonCexCuxgGD8fKnBLLzk2i9uM4kmcmGyyev2R5YDs+rafMYZ89RvaGY1mW8T7C5au0TyYaEeHBGng==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-annotate-as-pure@8.0.0': + resolution: {integrity: sha512-NSpMkMsvvZqzThJ0p1B02cbtA2ObEyfBvq950bmNkyxsxvcxwhvvCB036rKhlEnuBBo30bOrk13u3FzlKSoRrw==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-compilation-targets@8.0.7': + resolution: {integrity: sha512-ilAZCdOOlOVA7dQbaFNw2f/59p6GW33NxTopc3DvEE3efp3ZXTrGX/yZScaKw8/vd9bq31Ag0EcXiLw32bAgJg==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-create-class-features-plugin@8.0.7': + resolution: {integrity: sha512-7ug3KrOhNVPPxFFLTel0/pMzimKzU/vTlNJKVL/dKguCpmNJZjjibyFbWg+Qs8QHmiIZPNuZ2UNnDGdHWGEpOg==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + + '@babel/helper-globals@8.0.6': + resolution: {integrity: sha512-OdnA/N52LhzFpeUuVz5YGuSWjc7TPHiFmVYZbPlSgExocO2GwbxVpSni9MVs5wwW+wZ4kPuwBEBN9pIPDYz1mA==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-member-expression-to-functions@8.0.5': + resolution: {integrity: sha512-GLe05QD98BkNFTkjaqeqF9QSRoHLKrrB4tpoplyQuuPrQJ72rtmkM4wvqJLX/sjZPqkbK5MUYSsuUTqdJoOVjA==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-optimise-call-expression@8.0.0': + resolution: {integrity: sha512-3W6satvtPuCUkUx63S2jMoW9EQNYkADgs1HTfufmL7gCmAulHMKupA/12WNz4A0GMMFn/YnWWwqOT9IZrJHQjg==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-plugin-utils@8.0.1': + resolution: {integrity: sha512-3PKFgjTyPlhFhorfP+SjKQxLViIL++zWjFOO4hGriYU+Bsm983DxEM1JmDRJVWXV0O9npu+xXRqz7Pbd3mh70g==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + + '@babel/helper-replace-supers@8.0.1': + resolution: {integrity: sha512-B1SZADIcy3tmH8CmWvj4SHi/oAPom4UL3uknTc2QRNsPVLFk/sPnZvQL/8kj7Y5omvjMqie0vklvs6XM4OLW5Q==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@8.0.0': + resolution: {integrity: sha512-xmCA9kP3IhySsqhzwIdWGlDN/1A4cCKNBO/uwZx/3YzmDoMePwno2Q5/Bq0q+tYaKbeF940YiKV/kaW8Mzvpjw==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-string-parser@8.0.6': + resolution: {integrity: sha512-+6HYEBnsDRZHJtUTAEfMQd0zMDqdFHS7C+5vAsEZqBUr3vEMWOWlHJ0Jz1gS8jJIlCvLsuA6ivmeoqzH936YcA==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-validator-identifier@8.0.6': + resolution: {integrity: sha512-HYx0YmuchRxRSpnjvcNffnPS8DCauKNmnumIuHG3jnQAVewRA7kfJGwF13ayEpSZs7s4R/oBH4eppuXcAQd5JQ==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helper-validator-option@8.0.0': + resolution: {integrity: sha512-U4Dybxh4WESWHt5XhBeExi4DrY0/DNK1aHpQbsrQXCUbFHuMweT0TpLEWKvaraV2Y6fS+ZXunsZ8zIuZIgvF2Q==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/helpers@8.0.7': + resolution: {integrity: sha512-5dMj5kFwS2AY7Dt4PZp4px3c5ThMbbEa7tZfuHTncCGSFYq8uoA1ufDE1IS/lYpQedE+3+GQ3cPZUiplIu195w==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/parser@8.0.7': + resolution: {integrity: sha512-UkDwEbPO1px2JQSrdh4qIgaH1JgG7GO/pFeJkpxhDxIETkT/QvGpnigXIw75ViHYPtIgKITmVUJqLjiO+JuWjA==} + engines: {node: ^22.18.0 || >=24.11.0} + hasBin: true + + '@babel/plugin-proposal-decorators@8.0.2': + resolution: {integrity: sha512-+C6O6KKXU7BBq1GNaIkFJxrALUVGRcr+WeWm4OcuRl3h+l/CmNfcTLMrT2Lm3uvGBimBH/8pEBRrXJFLoO67Gg==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + + '@babel/plugin-syntax-decorators@8.0.1': + resolution: {integrity: sha512-NI+0S/6MvR6GlcQFwjDZ+WIc2qvG6TXN534lYs9llNldwW4b7Dh6KTtk030FA0xWdYGs4t1lWo+OEWN8wGB+Nw==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + + '@babel/runtime-corejs3@7.29.10': + resolution: {integrity: sha512-R4FKrg4Vy0hB7PfAxf9LOorEPd5/36SCIXPXAvjlQaQmPvtrjwoDXV15jsSm2ecsqBW1Iewwb7mEnG83xIEApg==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.29.10': + resolution: {integrity: sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==} + engines: {node: '>=6.9.0'} + + '@babel/template@8.0.0': + resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/traverse@8.0.7': + resolution: {integrity: sha512-bVV0brinsTWgc6ptSIoQo3GbITtl0VZAqEUJbHHcyfDPEu+q/fEvlYEa+6H85HoK8IdksKBFtKJbJFZ6Kff+zg==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/types@8.0.6': + resolution: {integrity: sha512-c+xgSWboV2pdwXP67BUWDVRHi2BO5Q3KwxyFVs7taVTY+fsK47/L51ZXQoV9rozHJDNHvJ4v4WEsI/IlxV2l2A==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@borewit/text-codec@0.2.2': + resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} + + '@cfworker/json-schema@4.1.1': + resolution: {integrity: sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==} + + '@chat-adapter/catalog@4.43.0': + resolution: {integrity: sha512-JRH40HwYIXdIiwSc/gNw65q5T/gaf691n4//2YOhjRE4YO9KzSFJ/N+RrTD3M8iGz2jI4Jg92wb6OAqfYsAkTQ==} + engines: {node: '>=20'} + + '@cloudflare/codemode@0.4.4': + resolution: {integrity: sha512-GL0IF7NiHwAC222riEYGX75NHcnhTornAPfRI0Mj3Ig7C1y9H89FL0xs+pdflIF74eecNkzynsA+JdCIkGvKeA==} + peerDependencies: + '@modelcontextprotocol/sdk': 1.31.0 + '@tanstack/ai': '>=0.8.0 <1.0.0' + ai: ^6.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + '@tanstack/ai': + optional: true + ai: + optional: true + zod: + optional: true + + '@cloudflare/codemode@0.5.4': + resolution: {integrity: sha512-/iyoiYNKYai961R1m704hmLbzg280C7ut3zZ2GIgaA1VSQMetjUmsS2t9YPCuLu2TZ8bOSoUtEz9UmNS4QmbFQ==} + peerDependencies: + '@modelcontextprotocol/sdk': 1.31.0 + '@tanstack/ai': '>=0.8.0 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + '@tanstack/ai': + optional: true + ai: + optional: true + zod: + optional: true + + '@cloudflare/kv-asset-handler@0.5.0': + resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==} + engines: {node: '>=22.0.0'} + + '@cloudflare/shell@0.4.3': + resolution: {integrity: sha512-6ZMKQZqdZeommh8LGFK5C2rep4byJfCuyjR4NBdMqn2wW9tbeDJORfDhP/No75MLx8nJeWdgeXvq3D2Ijpa0XA==} + + '@cloudflare/think@0.15.0': + resolution: {integrity: sha512-vI7YhGRrxbsnMEA6gVWD7aaWxa9dZOJBFuc+d9DZVLD7jfasO1egJ6LbS7VS6kfjCBETIzudi+wlmS3wYISEYg==} + hasBin: true + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.18.0 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + vite: '>=6 <9' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + vite: + optional: true + + '@cloudflare/think@0.15.1': + resolution: {integrity: sha512-BAMVRoBArhszewE0ONcq6sNxfB0QsXIZkhdZYl+6hXdUC/tHShRK1ZDaGhHuWhDBBGYsPY07ploFy4WOmCLkwQ==} + hasBin: true + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.18.0 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + vite: '>=6 <9' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + vite: + optional: true + + '@cloudflare/think@0.16.0': + resolution: {integrity: sha512-SVUJR+ENNL/eu7L5fNZCYALd72DRJYSiu7efNyr6hzNwFXYZSZz0Ecz06DoPLfN6k+F5ABO+0CHLVLAfAtr7dA==} + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.20.2 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + + '@cloudflare/think@0.17.0': + resolution: {integrity: sha512-tnfMZSqSz1dhfBx0io/mXMJE2huwJc2kTPAkx55y1bTUQwt9A2uONBmN1FixNsI9DFp1zXJDzcO0juGFKfTyLQ==} + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.20.2 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + + '@cloudflare/think@0.18.0': + resolution: {integrity: sha512-eN3gZvO05UPucAaQ9GfIu5iKhMeRKqd+NzxfNdi3rhbAHhsTC3ckxPnXNlBmr8Pg0zcvaJK69KhWPv4AySeexQ==} + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.23.0 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + + '@cloudflare/think@0.19.0': + resolution: {integrity: sha512-7xYaVeQJA4Xnwuo2R5/zhbUjWftvKzVjdsZnOSYjo+BqJ+hbizemW8fCt1QTTP+TDixgXXiOQNlOmyNJXjTYUw==} + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.24.0 <1.0.0' + ai: ^6.0.0 || ^7.0.0 + react: ^19.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + + '@cloudflare/think@0.20.0': + resolution: {integrity: sha512-1+BMb0XhALPDmCbzbPhITITANrIqBBYCT0sEIHFSbGOwGhWKLmblzdw8YP/FySdXuYko+y5PIcCXoxjNz0Ji1g==} + peerDependencies: + '@ai-sdk/react': ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.25.0 <1.0.0' + ai: ^7.0.0 + react: ^19.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + + '@cloudflare/think@0.20.1': + resolution: {integrity: sha512-gUGs1wA62hSFeLhFzxILQyJblV8QhtV58queJaGmjiKVdtQl8P4jRybJcOMpexWIiUXpruQFCa7mEzxKbTYJ8A==} + peerDependencies: + '@ai-sdk/react': ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.25.0 <1.0.0' + ai: ^7.0.0 + react: ^19.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + + '@cloudflare/think@0.20.2': + resolution: {integrity: sha512-6hkdWYlS3n00tbPwQ6eT6pcHJ9W1POlNgVrZWbwL7biO77/tX80tBwORoujMtTMdc3OaLjb7L5MokAy6bjFO/Q==} + peerDependencies: + '@ai-sdk/react': ^4.0.0 + '@chat-adapter/telegram': ^4.29.0 + agents: '>=0.28.0 <1.0.0' + ai: ^7.0.0 + react: ^19.0.0 + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@chat-adapter/telegram': + optional: true + react: + optional: true + + '@cloudflare/unenv-preset@2.16.1': + resolution: {integrity: sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==} + peerDependencies: + unenv: 2.0.0-rc.24 + workerd: '>1.20260305.0 <2.0.0-0' + peerDependenciesMeta: + workerd: + optional: true + + '@cloudflare/vite-plugin@1.45.1': + resolution: {integrity: sha512-C+iDpO9pVH7IqrjdYtUV+obcTAdpiNk0OSinGEZZyd2ZWyGVjGk7iJ2p3xpMBpZuTa1I4hfAECNp0yN/8f3PIQ==} + hasBin: true + peerDependencies: + vite: ^6.1.0 || ^7.0.0 || ^8.0.0 + wrangler: ^4.112.0 + + '@cloudflare/workerd-darwin-64@1.20260714.1': + resolution: {integrity: sha512-ZWXqAN8G7Cx9hMRQuk+59ziJhR3j1F4iO+Qs8aHdfKZ3Dq5Yi/57xvkJTgCGBnW1YU/L78r8f6HEy51bwbTpNw==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + + '@cloudflare/workerd-darwin-arm64@1.20260714.1': + resolution: {integrity: sha512-tueWxWC3wyCbMG6zRAxsMXX0YLgrRWbiAPYFQ2uJ7dUH8G+5E7UTWaQS9B1HdJ0bpKFW1NWxhs1o2noKVFSUYg==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + + '@cloudflare/workerd-linux-64@1.20260714.1': + resolution: {integrity: sha512-1VChTZRb0l0F7R4e1G5RtLKV4oFi6x+rQgxh2+yu887j3l/3TLgatuv1L8/5zhc9gKEhATTxOh0e52Rtd9dDWQ==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + + '@cloudflare/workerd-linux-arm64@1.20260714.1': + resolution: {integrity: sha512-rMm3G+NirG2UdgHIRDdF1asNC6FqgIzZzkRG+VDhhDGcVxAQwvrMT1E38BivEvHr3G04MB4AfhcOczX0+GtRkQ==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + + '@cloudflare/workerd-windows-64@1.20260714.1': + resolution: {integrity: sha512-cGqnU3Hg2YZS/k3SAqrMp1DjpdsyFde72tWltdl6ZT9+SFz/Zrk/8gyTU1TcxC4YApXeNVH5TyU5cOGPgUJ0pg==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + + '@cloudflare/workers-types@5.20261019.1': + resolution: {integrity: sha512-llvvy7WBVhK+OfykyBkG9A7OgsGvgwHSNyU40XGVkiy/xVFy0t/xflyhEBHT+U59yQECZQbmcZsJtqCNnLpIRg==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@emnapi/runtime@1.11.3': + resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} + + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@hono/node-server@2.1.5': + resolution: {integrity: sha512-MgP/I06GdvsilDspMk/qmRzpk8LOUStP6jFAbSRi40W09DhoyUn+Mj7eyKICPqeYKybOjVFLVIAQzvu1bfIa7Q==} + engines: {node: '>=20'} + peerDependencies: + hono: 4.13.7 + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.35.5': + resolution: {integrity: sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.35.5': + resolution: {integrity: sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [darwin] + + '@img/sharp-freebsd-wasm32@0.35.5': + resolution: {integrity: sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==} + engines: {node: '>=20.9.0'} + os: [freebsd] + + '@img/sharp-libvips-darwin-arm64@1.3.4': + resolution: {integrity: sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.3.4': + resolution: {integrity: sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.3.4': + resolution: {integrity: sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.3.4': + resolution: {integrity: sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.3.4': + resolution: {integrity: sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.3.4': + resolution: {integrity: sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.3.4': + resolution: {integrity: sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.3.4': + resolution: {integrity: sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.3.4': + resolution: {integrity: sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.3.4': + resolution: {integrity: sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.35.5': + resolution: {integrity: sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.35.5': + resolution: {integrity: sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==} + engines: {node: '>=20.9.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.35.5': + resolution: {integrity: sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==} + engines: {node: '>=20.9.0'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.35.5': + resolution: {integrity: sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==} + engines: {node: '>=20.9.0'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.35.5': + resolution: {integrity: sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==} + engines: {node: '>=20.9.0'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.35.5': + resolution: {integrity: sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.35.5': + resolution: {integrity: sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.35.5': + resolution: {integrity: sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.35.5': + resolution: {integrity: sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==} + engines: {node: '>=20.9.0'} + + '@img/sharp-webcontainers-wasm32@0.35.5': + resolution: {integrity: sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==} + engines: {node: '>=20.9.0'} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.35.5': + resolution: {integrity: sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.35.5': + resolution: {integrity: sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==} + engines: {node: ^20.9.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.35.5': + resolution: {integrity: sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [win32] + + '@jridgewell/gen-mapping@0.4.0-beta.0': + resolution: {integrity: sha512-JdGNkbE4GlNPYQhM0L95fBQr7ctLZJ276QXQLTad4t1oSdnnCI3fDq9DW3BqYAWv8Wc3+HS+4Gsii1oPMCfz1w==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@mixmark-io/domino@2.2.0': + resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} + + '@modelcontextprotocol/client@2.0.0': + resolution: {integrity: sha512-8f1OghQ2rjzIOfqgUCP+8GiUWqRs89njoWLNqAe8kWmDePv3s1fZXseej+QXemssEuuOvLLmLO/kqM3IQHtISw==} + engines: {node: '>=20'} + + '@modelcontextprotocol/core@2.0.0': + resolution: {integrity: sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==} + engines: {node: '>=20'} + + '@modelcontextprotocol/sdk@1.31.0': + resolution: {integrity: sha512-UvTMgnNlnIBO/22ob2RcVGDlcvOslQs8T59+FTGdA0L27a39fdGF/EDETNtDVK4DZGpwomlsYpRdA8UXcVL/pw==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + + '@modelcontextprotocol/server@2.0.0': + resolution: {integrity: sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==} + engines: {node: '>=20'} + + '@mongodb-js/zstd@7.0.0': + resolution: {integrity: sha512-mQ2s0pYYiav+tzCDR05Zptem8Ey2v8s11lri5RKGhTtL4COVCvVCk5vtyRYNT+9L8qSfyOqqefF9UtnW8mC5jA==} + engines: {node: '>= 20.19.0'} + + '@napi-rs/lzma-linux-x64-gnu@1.5.1': + resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==} + engines: {node: ^22.20 || ^24.12 || >=25} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@nodable/entities@3.1.0': + resolution: {integrity: sha512-LsS/DjHr+uDM647Gru/cA8+J3a3HfhttwCKLyuoyN7yXTFCxKBtSgMQBvrW9yNPa2/zDRUNuGPaH5QUFoa4arQ==} + + '@oxc-project/types@0.154.0': + resolution: {integrity: sha512-KYOUGQFlLWR+s4QMV2Q9ko38TZm7EdO87Qm7rvZLqk/webse/cDjtyxKhg/47l0byCbs/k46LT8qc4PKjAikzA==} + + '@poppinss/colors@4.1.6': + resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} + + '@poppinss/dumper@0.6.5': + resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==} + + '@poppinss/exception@1.2.3': + resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + + '@rolldown/binding-android-arm-eabi@1.2.14': + resolution: {integrity: sha512-aWR+XKH9+rW7m5fWq/5360J3mHycrx/o6xZM2DQFdJnTMdyP7/WzxPjhtLbVWdKo2y612/4U1bWqb3HQhiF7vg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@rolldown/binding-android-arm64@1.2.14': + resolution: {integrity: sha512-QiVxHofl6A8lQU7WAtOUY4QMVZXohxwz7WJJoeh8NBEUyKfIkMRKhYyq8az/1RypNiIXzNTtiS6KwHz0erxYRQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.14': + resolution: {integrity: sha512-lTQOzHuBIooh3jIr5XINQkjPGEuGy+Dsy0meXDr6Sjty0b99kYgGh4uBC/8mJX1T0kC8d6S0aPP1Y+bHkh6aBw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.14': + resolution: {integrity: sha512-hyMKEGatjmBYCs/Q4sbIcL/GqpFEqsX3wc+HYVQ/85A4rxc1o7rPm4DUI4GV4k/h0ITddwFSGpqQunI14GXjTA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.14': + resolution: {integrity: sha512-u371GbXoVXrEgP20PwzoGNOdAOqAMhzo19JzzY+V4YmmnC+DTOoqdbMu+O+54emM59Mik/UdrtWgcuEDKWRPKA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.14': + resolution: {integrity: sha512-BqwKsdZQf6EqVWr8fv2MrDYzAvOZ7+NYFSJESRGs87fkseEhs0TU9TXgRJTkZoRRkxTizyEg1LKUXfU3/78uqg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.14': + resolution: {integrity: sha512-SD9kY8M009x/7s57Z1dgUVlP5+uYBgKQK0Tkr1WIWngrtUJmRCW1RJFMY7QDla2khXhmg2i5Io7MUjcmZNZ/KQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.2.14': + resolution: {integrity: sha512-BJ2CL19M6uuWesMgnqJzgxoI+N+eV7b0A9O9vLV42y+gitC41fNa8KElau1tHVzuLWX5GzEuxMPhAO0tQXQMkg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.2.14': + resolution: {integrity: sha512-4+Kl8daPV8NDHaD7mfCcc1pRM+Qg7ab8DyMm5FG5WoZgv4h2i3KFN1CybYBNbQqmuYm7ftJLvmMI1eHYJ22S/Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.2.14': + resolution: {integrity: sha512-V/h8ePq1fKDrmtFMz6xcCN3DKvuvMRrwwD1q0PkBeeo4DpK64biaKvqWGVxqCeYKqeRk7gE7/iKPxLCn08O97A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.2.14': + resolution: {integrity: sha512-WxalXzgrLVpKC93xfpaJ3gCXUWzeCr+FRCbDVD2mUAy4L6Vo3lNVz0epUEUpxPWJkLNYUwM4OSIikv36OJ9mLg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.2.14': + resolution: {integrity: sha512-3G3tnAmTpdk9jO3GQtyHXqeFD2SlecfTws/Y3M2mmj9nMBwwuLT4kur8sZKeu7ENUHSpVO3cIsm5A52LEWWwlg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.2.14': + resolution: {integrity: sha512-qyr5XiNGxm2ytx17vvtcJ9nXn6v1gENETi503bJx3OGwZ1tSonj7BosxbMa/xeAfSl5iS9X6KjEWYXLu6v1L7Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.14': + resolution: {integrity: sha512-oA4o5o0S2yB199YyYXDzKUv1Z56Rc+mgOjwm7Z/vJ9Z8igiDPYvoOuDyo6g7AK/ZaF09nPhDKVnGBcYHO11GXA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.14': + resolution: {integrity: sha512-9mE94bf2GZUaR/fUSXCMpBoWkctu421Mi0ORpm4zqfbkjKep7RxzPFa5etcGs5h+2KApoWBOA/hAJa/7saGgEQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/plugin-babel@0.2.4': + resolution: {integrity: sha512-ygmm2j/mN+aCvstHo0x3IOu4uc6LqXT9SJ3q4kpfG/+Yhfz0B+E47FITcC0FljZADwUFARP6E2kiE+Lc26D8wg==} + engines: {node: '>=22.12.0 || ^24.0.0'} + peerDependencies: + '@babel/core': ^7.29.0 || ^8.0.0-rc.1 + '@babel/plugin-transform-runtime': ^7.29.0 || ^8.0.0-rc.1 + '@babel/runtime': ^7.27.0 || ^8.0.0-rc.1 + rolldown: ^1.0.0-rc.5 + vite: ^8.0.0 + peerDependenciesMeta: + '@babel/plugin-transform-runtime': + optional: true + '@babel/runtime': + optional: true + vite: + optional: true + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@rollup/rollup-android-arm-eabi@4.64.12': + resolution: {integrity: sha512-Z8lz+5UOiCJLonjeqwJlhUtHA/Sr6R1AidkccQxdWF0nigNzP81aLoU+udgOaGfL5s1uzFXzcux/pCwGAMu0lw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.64.12': + resolution: {integrity: sha512-+tKxNa2psFmiTb0KfXlXs4Yj7vkEhzAvZ0DrQ5+0gWHQJM10jSleQ3l1FIVm5uvD53YM8lHfM4mgCLDDN9f1Gg==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.64.12': + resolution: {integrity: sha512-iiripdfvyRBugV55/Dk7GplNXQtN/PG85OcKeveU1z2UkTg0MofbBF1qk//qgPWiqJbVvQcXAVCfE56oDGO4EQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.64.12': + resolution: {integrity: sha512-BmATib8swSMAagWNIfDZMnb+k34RXR4bbGOUfZgK8lLlniuMyVoSDDXCOGkdhtUmBXL4aygDh7bhjQ+TmhTvIw==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.64.12': + resolution: {integrity: sha512-GzrO0CiUq8vcAI/hYJuIcp6wNm3T3YhOpumYtf9Z3Fz+cfN1VESCVfy7EPcM3/m2K8l+Gn2U+4XtNZjwhUXctQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.64.12': + resolution: {integrity: sha512-Dpta6gigm4o6SYioXtTkZBlGLA/Sl6OpzgLqY+51uafJE2blPejAtR1w82CVLPN+F9cvo1+/em92x/zcOgY0uQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.64.12': + resolution: {integrity: sha512-YpeDwQ5uFaogRvytNC8RK0keDO65kI5wNEhGSs+4GiJc3KHhxj4j5cnQh2nCu9ybJj6RP0/ycB6bkN0yFJ9I+w==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.64.12': + resolution: {integrity: sha512-LQrB3/sImIr1ycrlEyaApOLH1rAy8JV4/dH4eoK817aWATdcs4fESXz53/w72NwDnwPM5zEUpoL7socH4ZDnwA==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.64.12': + resolution: {integrity: sha512-iAF2iYu9S4SBfNsb4k0ewNBjO83WxHEltIuKQBGMzEKFgrYfmJn+gatBDXR2t/0zJN0UW0kzR4rfvQ1UHzkZ1A==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.64.12': + resolution: {integrity: sha512-0MQdRtdbirJCXPIVeW/hd/LXLR8Qz96pc+2EBptuuV5q/zSGOzND7SZt8gBTE58NC9cUG/8UxcUXQiKRZ2WzzA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.64.12': + resolution: {integrity: sha512-yGDEwn0AGnrY/KCz2oY8R9KKNiQnTcwNuCWXeSXF0VLxXzlqoCgaS5QHsf1lbQvKWwPuN2Czkjk1wXRCBONTOQ==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.64.12': + resolution: {integrity: sha512-AjlbD0efZEhHaJ3bsNjxSFDoguNq6VZvC+FKGJGBCA+ZN7BrZq2TuuSWFa6AI8IpOeuvhp2LoYcP7jiZwmtU0Q==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.64.12': + resolution: {integrity: sha512-sDW0CiPoUCEEUV25uBG5sJ2gKe75DJqLpj91m1eK1vKffywyY7v4i6q1450ZuR6QW4NArXg7JpbMGgKU8di3HQ==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.64.12': + resolution: {integrity: sha512-VTQYUhMjl8kv999VuYqScgv7P9cR9KuxI/6bkUsEa3bsswqG0+otFjuLZmJ1U+ffEP4IAz0jxOeV0DX6NRBhjg==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.64.12': + resolution: {integrity: sha512-ppsKwpSjNrzJ8hge3Z3uiCcoRgAAQk2tU7auy3MFF348ffWRldFPnWIT/a/enK7huijlTfnwn4DYpDoapEb45A==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.64.12': + resolution: {integrity: sha512-Gc3cVRC1trFH+GFWWTsJz6YuD4u75fzr/q99jqQGimonN/zvN6Wecck5WGzllOHj+XYXHcq0Ibor0tanGjfI6A==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.64.12': + resolution: {integrity: sha512-pjmDTFStvwFE3shTeUDvSDiSp8/qAf5bQXejcEUDDavWz4jEhTIpCdpS06G0PEwSCSNK0Lngjz2v9l4hk3Z74A==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.64.12': + resolution: {integrity: sha512-mkbjxPqpR91u1JD7xY4aLZhr/Mqka4/RqGcG4WNGgN/lC1o7TzyCyqJoSJXp9qVVxMwpJGFlEF1VlERb+Ghw1Q==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.64.12': + resolution: {integrity: sha512-vIeut2LkuVc3gcsawLJPahNAzvzBcFRhu2O+yVb//BuQKz7PIItMF0piXRbN/lIDO3d68TSDd368Vg6YwgTybw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.64.12': + resolution: {integrity: sha512-3Sx+D3r9oPkTdNUcPrIRM2Am+vzEV6VGWoImHG4ZVK2jJeOW+eDjLeTm6nvu/z/m0fiX2YmGLXIypblc336MXg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.64.12': + resolution: {integrity: sha512-Nn2xh0teFnl71EiiUrKvECWcdGXtWF8q0uGclYwXGVw6QClGAcME0/bJSGdK+xIvd6MLEKYmjkTUvCBV+7m5Kw==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.64.12': + resolution: {integrity: sha512-n1/0H9TS+kBa4xp6n9aV7yiynBNfmerjkj2nAMIfY0ZHv1zShWRXnsAuAPAH0sfEK4ZSMK+z24q2RjAPFLCN1w==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.64.12': + resolution: {integrity: sha512-AdlDbQpsLfGlsHr1NfLZFtdnvxCKNp9TwlYVYExs8JJLWjLafUQEKJk0r9zUbmU57mw9nglMEvzqPHuLWYmaKw==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.64.12': + resolution: {integrity: sha512-u5SSUJBHod51UamjkigSr+JPre6xMy5vaWTTV2K0SnFG4RuKyYpf66dTSLFKX2cwaldpwyBurXPUCxq8riQMEg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.64.12': + resolution: {integrity: sha512-j5rXD4R/4DM5+V991AA9xOnG2Rwu2g3p5TPgu1Eu7apju0NUrLl+Bn/KpWc6wYJtlXqzwz1r+LNV1JeBU4VGvw==} + cpu: [x64] + os: [win32] + + '@sindresorhus/is@7.2.0': + resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} + engines: {node: '>=18'} + + '@speed-highlight/core@1.2.24': + resolution: {integrity: sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tokenizer/inflate@0.4.1': + resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} + engines: {node: '>=18'} + + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/gensync@1.0.5': + resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} + + '@types/jsesc@2.5.1': + resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@vercel/oidc@3.2.0': + resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} + engines: {node: '>= 20'} + + '@workflow/serde@4.1.0': + resolution: {integrity: sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==} + + '@workflow/serde@4.1.0-beta.2': + resolution: {integrity: sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww==} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agents@0.18.0: + resolution: {integrity: sha512-ozQCDZrJerDMW/2/X3N+y6yzB4PAfiMtPN4jhK5fD+CFdYfc35k0mqNf/GTWzMA6Pc7WekOB/nFaAlIMrH9WvA==} + hasBin: true + peerDependencies: + '@ai-sdk/react': ^3.0.204 + '@tanstack/ai': '>=0.10.2 <1.0.0' + '@x402/core': ^2.0.0 + '@x402/evm': ^2.0.0 + ai: ^6.0.0 + chat: ^4.29.0 + just-bash: ^3.0.0 + react: ^19.0.0 + vite: '>=6.0.0 <9.0.0' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@tanstack/ai': + optional: true + '@x402/core': + optional: true + '@x402/evm': + optional: true + ai: + optional: true + chat: + optional: true + just-bash: + optional: true + vite: + optional: true + + agents@0.22.0: + resolution: {integrity: sha512-dIy/BRdO5GSqdOIp0pmkcLmHCCxIKb4RBByXFXmXG6Nc6WBSNYRXoLLDvWj2fJAfi4l5/OndJjZuBAP0vW0DZQ==} + peerDependencies: + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@cloudflare/codemode': '>=0.5.0' + '@modelcontextprotocol/client': 2.0.0 + '@modelcontextprotocol/sdk': 1.31.0 + '@modelcontextprotocol/server': 2.0.0 + '@tanstack/ai': '>=0.10.2 <1.0.0' + '@x402/core': ^2.0.0 + '@x402/evm': ^2.0.0 + ai: ^6.0.0 || ^7.0.0 + chat: ^4.29.0 + just-bash: ^3.0.0 + react: ^19.0.0 + vite: '>=6.0.0 <9.0.0' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/react': + optional: true + '@cloudflare/codemode': + optional: true + '@tanstack/ai': + optional: true + '@x402/core': + optional: true + '@x402/evm': + optional: true + ai: + optional: true + chat: + optional: true + just-bash: + optional: true + react: + optional: true + vite: + optional: true + + agents@0.28.0: + resolution: {integrity: sha512-5nYoykTqL6HWLwRyPP9XL4triRg+kkc6W1Ovt58lMz3oLbChRst6GWQVU3LvLgve8YIbo1SvQp0IR4TOrxAD6g==} + hasBin: true + peerDependencies: + '@ai-sdk/provider': ^4.0.0 + '@ai-sdk/react': ^3.0.0 || ^4.0.0 + '@cloudflare/codemode': '>=0.5.0' + '@earendil-works/pi-ai': ^1.0.0 + '@earendil-works/pi-durable': ^1.0.0 + '@modelcontextprotocol/client': 2.0.0 + '@modelcontextprotocol/sdk': 1.31.0 + '@modelcontextprotocol/server': 2.0.0 + '@opencode/plugin': ^2.0.24 + '@opencode/sdk': ^2.0.24 + '@tanstack/ai': '>=0.10.2 <1.0.0' + '@x402/core': ^2.0.0 + '@x402/evm': ^2.0.0 + ai: ^6.0.0 || ^7.0.0 + chat: ^4.29.0 + just-bash: ^3.0.0 + react: ^19.0.0 + vite: '>=6.0.0 <9.0.0' + zod: ^4.0.0 + peerDependenciesMeta: + '@ai-sdk/provider': + optional: true + '@ai-sdk/react': + optional: true + '@cloudflare/codemode': + optional: true + '@earendil-works/pi-ai': + optional: true + '@earendil-works/pi-durable': + optional: true + '@opencode/plugin': + optional: true + '@opencode/sdk': + optional: true + '@tanstack/ai': + optional: true + '@x402/core': + optional: true + '@x402/evm': + optional: true + ai: + optional: true + chat: + optional: true + just-bash: + optional: true + react: + optional: true + vite: + optional: true + + ai@7.0.138: + resolution: {integrity: sha512-rB2grfrM9se2GY/au4e5Eq0xadPM4+a+ip3EZ0ofedIPU8/GETWGjXO6gbzQDA+7nMaZnaUVaX2f+ByAj/LF8w==} + engines: {node: '>=22'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + ansi-regex@6.4.0: + resolution: {integrity: sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==} + engines: {node: '>=12'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + anynum@1.0.1: + resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==} + + async-lock@1.4.1: + resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + aywson@0.0.16: + resolution: {integrity: sha512-xLFICM6OgSMcysNHCgrhri7hpcn0TfuyU5KxtjpIAJAUuD0Bjph2pSkLgxjn45iQBjBxs4S5Fq+RmXhIYuQtNw==} + hasBin: true + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.11.30: + resolution: {integrity: sha512-YJs6Pz17RMNv8HoyKREtCY38E3BV1nPkWVmIb+XN1uHC1Vqt3KZCH/uJH9ZKRoiKb/icZ6tvehyee6RZNbFfRA==} + engines: {node: '>=6.0.0'} + hasBin: true + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + blake3-wasm@2.1.5: + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + + body-parser@2.3.0: + resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} + engines: {node: '>=18'} + + browserslist@4.29.4: + resolution: {integrity: sha512-2TcbbiwXEq+N0kD36tykpCfyyQigUXmuwNQbnPp4Xk4PX9JOqVIKjJlIDjpH7uY6tmRGoAd+apeT1p60T8wsdA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + caniuse-lite@1.0.30001817: + resolution: {integrity: sha512-uZ1JG80BwhtMalIAGPxPfmNhHyd/B/nTdr3hITWlRamSyAdUStP1Gop01e7SD5q6J90ixJvWDbvmiFVfDgn4bw==} + + capnweb@0.12.0: + resolution: {integrity: sha512-jgZ/LMtMVTi+RVlooIslH78Gg23XbDTdvcLghWx3oz17D6u5GuJARt+uhZk/wcTo+f81eeabfnow4d3zLBj+JQ==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + chat@4.43.0: + resolution: {integrity: sha512-9ICxMewK1+4J0pEbR7eMBTh3JCL3NkyDHAgGrU/gblyyw/+QUcwFHCXIoQMt0Xlyup1c5smS0/gYytTt8NVc6w==} + engines: {node: '>=20'} + peerDependencies: + ai: ^6.0.182 || ^7.0.0 + workflow: ^5.0.0-beta.35 + zod: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + ai: + optional: true + workflow: + optional: true + zod: + optional: true + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + clean-git-ref@2.0.1: + resolution: {integrity: sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==} + + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + + content-disposition@2.0.1: + resolution: {integrity: sha512-e+H0ZXHSWYrENhQzw1LPuP4oF5MzVKmDU6d3hxlvaPEYLLg62MxtQNPRx4SYSuYJSBUgnQIG4HIN2tEtNv7Dog==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + content-type@2.1.0: + resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} + engines: {node: '>=18'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + core-js-pure@3.51.0: + resolution: {integrity: sha512-NE4SFDJ+qzQeqHG2vVSNwopzS6zZNPYJ5kinIqs+OofTqGzOmICgT89E/yvS9XY7rwb3eU1utWXTJ9nVFqv74A==} + + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + create-think@0.1.1: + resolution: {integrity: sha512-C8+k9fPArd1B0nnDUV83Fjw7hzJyaY+LN4v3Va+k4enMlSw0ZvyJERjJwntcp+1Snos+sy07SQYpV+1k10zARQ==} + hasBin: true + + cron-schedule@6.0.0: + resolution: {integrity: sha512-BoZaseYGXOo5j5HUwTaegIog3JJbuH4BbrY9A1ArLjXpy+RWb3mV28F/9Gv1dDA7E2L8kngWva4NWisnLTyfgQ==} + engines: {node: '>=20'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + dc-browser@1.0.4: + resolution: {integrity: sha512-7oEtnzNlcE+hr4OvO3GR6Gndgw8BhW+wKOEwMqSleyY7N29jbAxzyW5BaJl7qBCw+6OIxfMWtY0T+6dxq8RWLw==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff3@0.0.3: + resolution: {integrity: sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==} + + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.460: + resolution: {integrity: sha512-rRaVC7bNUyGsL+GMtmZfv3AfgG6za7gE9v5bT0PIbjEerddA0IQ+tCK05NFAXqCpNlrxBZqbFqquyxHRQONHTA==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + empathic@2.1.0: + resolution: {integrity: sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==} + engines: {node: '>=14'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-polyfill@0.0.4: + resolution: {integrity: sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ==} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + eventsource-parser@3.1.1: + resolution: {integrity: sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + + express-rate-limit@8.7.1: + resolution: {integrity: sha512-2FXbqkygil3mZiXzEtM0IjE/UBmBNot0J1GEVrJT4JbrvwOSoEtqtO+wHbiMQELWe1eNvHoYRg2dkjOid+6JkA==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.3.0: + resolution: {integrity: sha512-qCqy1xSoaugxOD4IVHb1ZWdkvCF2W3aE2okKouWj8VwJ+ztskSiXoBnCSJqfKT+cVPJhuJqe9YLbY425+Zh00g==} + engines: {node: '>= 18'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-uri@3.1.8: + resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} + + fast-xml-builder@1.3.1: + resolution: {integrity: sha512-pIM/1n3ntFXKYrUZwW7QCK0gAW7XY+wzj1YMIV3tLDvPj/V+zTGJK5e3/4WJfwj0qWw2ElNXiTixda/R+3YSug==} + + fast-xml-parser@5.11.2: + resolution: {integrity: sha512-R9iDuNrQYeQut46cn2r2wHKn4HYzVDvDm5J1wW+koZewykv0yuO2HChTYeZtrULyHIDM9cj9TUXloCsueCQUog==} + hasBin: true + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-type@21.3.4: + resolution: {integrity: sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==} + engines: {node: '>=20'} + + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + flru@1.0.2: + resolution: {integrity: sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog==} + engines: {node: '>=6'} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.7.0: + resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + guarded-fetch@0.1.3: + resolution: {integrity: sha512-PSaNyJk8VJlUVEhMHPXT/Z/WgNrLBh43WaYQJiu1qvyCuPQA+kgFMNmAOxI3GU3uXrCkO/xRW11XjcswrksYOA==} + engines: {node: '>=20.19'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + hono@4.13.7: + resolution: {integrity: sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ==} + engines: {node: '>=16.9.0'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@6.0.0: + resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + ip-address@10.7.1: + resolution: {integrity: sha512-4OUAqU9Z1i3vCnS05hzGiFnEMDpQ+62pAD/MVQOp83fYyNC8GleCqaS0QikQBmcWCrKFiUs/B8ztRRiYOAXuCA==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipaddr.js@2.2.0: + resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} + engines: {node: '>= 10'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-unsafe@2.0.2: + resolution: {integrity: sha512-HgbIHPBH0KHHCcjLfGsCvhtPTVxjaAZlXjwdz7/GQC40SjSe4sfQsar8J5VFo8JOSbarkpV0OLG95bbaNd9aAQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isomorphic-git@1.44.3: + resolution: {integrity: sha512-xlEIMsVUrMfOR25F4jWB9He9s/rUHWsgfJJJ3zpdwFssv9X2QfoIUyYH9CEFok9yk2tx2UDipj2gJ+KVvV/qGA==} + engines: {node: '>=14.17'} + hasBin: true + + jose@6.2.13: + resolution: {integrity: sha512-7TIg10ZE1x82YediN+lcrPNvGMKge9yFHQD+Qho/b8y2adfugU3AsvvHfxV0fzyFllT6l9xCjf4RWY9g/Z9PJQ==} + + js-base64@3.9.4: + resolution: {integrity: sha512-PtOMXpEGuP0RRiRXsjzHzl44dMHxSu2CPvAhinupR1tBa88me+1DPqsobl7eupn5UukjLkln1ZnAOAOXOrYG0Q==} + + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + just-bash@3.6.0: + resolution: {integrity: sha512-2COjEgcHdqKXeQSiNfPAHmpwQx4S8wATaIwog83g2t645U5tom6FED4CBBdr3M+0ioX4xZ26eODw3/nD6RQ6xw==} + engines: {node: '>=20.19'} + hasBin: true + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-find-and-replace@3.0.3: + resolution: {integrity: sha512-xPgpDNl0/OXHsI7TlaIs22lWnH3KlpvZdXG1ET/m/YT2Hhdkx8lJV4kLphE6l9simyM4KPDFBwas08BgEob6Jw==} + + mdast-util-from-markdown@2.1.0: + resolution: {integrity: sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.1: + resolution: {integrity: sha512-OuJHqvr455pwu2OaOrir7dbzqs4jlWKOtlu9L6GjcIjjQwNyw02VntQsr/Ek6/A13vgnXfUhBekWRUP1OkNivw==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-markdown@2.2.0: + resolution: {integrity: sha512-2Jn/ADrHFFyyniBMi0bncTbJqU78K3/TEYvzvwrWWzD9MYPUa/Gm4r3nOeKFQg/PDM5BsbDYdc8ackW4NTY6NA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + media-typer@1.1.1: + resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + micromark-core-commonmark@2.0.4: + resolution: {integrity: sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.2: + resolution: {integrity: sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.1.0: + resolution: {integrity: sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-edit-map@1.0.0: + resolution: {integrity: sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.3: + resolution: {integrity: sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==} + + micromark@4.0.3: + resolution: {integrity: sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mimetext@3.0.28: + resolution: {integrity: sha512-eQXpbNrtxLCjUtiVbR/qR09dbPgZ2o+KR1uA7QKqGhbn8QV7HIL16mXXsobBL4/8TqoYh1us31kfz+dNfCev9g==} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + miniflare@4.20260714.0: + resolution: {integrity: sha512-MYlTCLdWCPqvrYY2uLwOjXwmglXuiHE3TGGkbOW4BwjUPa1r07E0iuHwrNDIs/sxK21r+o90Jx58AV2KeNdJZw==} + engines: {node: '>=22.0.0'} + hasBin: true + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minimisted@2.0.1: + resolution: {integrity: sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==} + + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + modern-tar@0.7.7: + resolution: {integrity: sha512-t9VmxaqrmANnEOBhpSDI6HD192Ge48k8vmWqQQL7hSFEqHEYwZbbsu49+aKLWZeRvFs3j1pMhXOqqF4kPlvjkQ==} + engines: {node: '>=18.0.0'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.20: + resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.1.16: + resolution: {integrity: sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==} + engines: {node: ^18 || >=20} + hasBin: true + + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + + negotiator@1.1.0: + resolution: {integrity: sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==} + engines: {node: '>=18'} + + node-abi@3.99.0: + resolution: {integrity: sha512-lLdwkeg2XUVPTHqWjPltTxH81zbQNbUWC+AEb9ni50KjxkUzAAx1HGtMT21sbntzfUGfIphhcklvs3imJeqDXw==} + engines: {node: '>=10'} + + node-addon-api@8.9.2: + resolution: {integrity: sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==} + engines: {node: ^18 || ^20 || >= 21} + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-liblzma@2.2.0: + resolution: {integrity: sha512-s0KzNOWwOJJgPG6wxg6cKohnAl9Wk/oW1KrQaVzJBjQwVcUGPQCzpR46Ximygjqj/3KhOrtJXnYMp/xYAXp75g==} + engines: {node: '>=16.0.0'} + hasBin: true + + node-releases@2.0.59: + resolution: {integrity: sha512-5qr2okC4ItAI0hG5SaV0HoYMpnM/Y6+Oqr7AmPYy/2uEoGvS+GbSKLeRxSS1uAdu59yz0ouzcuXievSgg///WA==} + engines: {node: '>=18'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + obug@3.0.0: + resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} + engines: {node: '>=12.20.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + papaparse@5.7.0: + resolution: {integrity: sha512-qBGxg/7Q3Kl9Wfhrz2Z74UnvnHTXLNG6jmKJFeBvP2+y4lV7So+7SR62+Zd47JvdrCkX+nDcnr0ObPzek/+6RA==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + partyserver@0.5.10: + resolution: {integrity: sha512-t2B3mhTL1IOxCsj8rZgn4TxTuub7oLhypjc1/fGPNsbgnn9OsHms6uR3QEd5bFJ/7xrFo771j3DdUlll8cxgBg==} + peerDependencies: + '@cloudflare/workers-types': ^4.20260424.1 || ^5.20260703.1 + + partysocket@1.3.0: + resolution: {integrity: sha512-1zToNyolZFK/7nuAw/K2bZrNzFqaZyRoCEkS+9vG6WSC5ikrN6qWRe96q6ImU51uptz2r+dAwSkwhJVdQi4LiA==} + peerDependencies: + react: '>=17' + peerDependenciesMeta: + react: + optional: true + + path-expression-matcher@1.6.2: + resolution: {integrity: sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==} + engines: {node: '>=14.0.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postal-mime@2.7.6: + resolution: {integrity: sha512-UUlyE2KlxmvwMGq060onF/VWU3zD6dVW31FwokQ5v26jWd35fbs2MoTFzh+jXnPwAyV2MULMKXcBInGOl5TO6Q==} + + postcss@8.5.31: + resolution: {integrity: sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==} + engines: {node: ^10 || ^12 || >=14} + + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. + hasBin: true + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + proxy-addr@2.0.8: + resolution: {integrity: sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==} + engines: {node: '>= 0.10'} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + qs@6.16.1: + resolution: {integrity: sha512-5Px6J7rfHBAGUhNQ3es4YzcOdBBw0SDcVtThJml4RdnKw4tKs2epA0kPZ+K8X+WiHktT93RHVcQ/3ym5aTCgtg==} + engines: {node: '>=0.6'} + + range-parser@1.3.0: + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + re2js@1.3.3: + resolution: {integrity: sha512-s/I5zEAo79SUK0Qw4dpZKpiMwbQ6Gz0KU2NRr7eaO4x/p2g7Vvmn3hdeXDg8VsaUjfj/ora+e9oi27LX/C9+mw==} + + react@19.3.1: + resolution: {integrity: sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==} + engines: {node: '>=0.10.0'} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readable-stream@4.8.0: + resolution: {integrity: sha512-2jhTTU3Eilp/2DMT71gbcoqC35eQHasMJH0RHkYxwlxIv3+FR6Y5xAFZIwEGLxKkjZYEFlsiMNIdwUqjK2lLHQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remend@1.4.0: + resolution: {integrity: sha512-mHiYhhwphs1IgIZmkToKLwJn0U99IjPXuutkA2acrNcG0vlEq2G4TGnd2eT0saIHwh2KjaCpvleHcsd5SAz96A==} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + rolldown@1.2.14: + resolution: {integrity: sha512-eTBTTqMR6uHKLgcUqpJP8ntzDI6V4LYA8negAMBEI7gkgVvOdrx6VsvS2Ym+83KhOPdLCHWJu0w7UQFJZhHKNw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rollup@4.64.12: + resolution: {integrity: sha512-GhAu8ZglZ61VWSX/ZW3K/qkazgURBIQL0/Yy51QsS8DPyebR5Cf/Z2PANJFpTU0aVZ9byJcyqR6xvBbkXhdGYQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + run@2.1.3: + resolution: {integrity: sha512-KUurW05zgjtZ2su0cBURC1q2RG/Uq0uzV3qURDsXqiKh03p9IXABQK4Qem56cFMqjT8TdQ2iTWsePrMprQWIRA==} + engines: {node: '>=20.19.0'} + peerDependencies: + typescript: '>=5.1.6 <7' + peerDependenciesMeta: + typescript: + optional: true + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + seek-bzip@2.0.0: + resolution: {integrity: sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==} + hasBin: true + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + + sharp@0.35.5: + resolution: {integrity: sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==} + engines: {node: '>=20.9.0'} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + smol-toml@1.9.0: + resolution: {integrity: sha512-hpd+HLON7HdZXqYchMM/+LaTTbdK0AU3NngIJ4KVyWbY9bfQqdL9cD+4yf6dUoU2Ap4VsU0JkQi6FxAI1B2mXQ==} + engines: {node: '>= 18'} + + source-map-js@1.2.2: + resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + sql.js@1.15.1: + resolution: {integrity: sha512-i0M/6s+lcl67Flm/1m8/AeVU5caDramlILXU/udUwpTQym2qKMSe2sJiXB5d5WXFB272aj4B2v1JbtQ93ID3Pg==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string-width@8.3.0: + resolution: {integrity: sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==} + engines: {node: '>=20'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strnum@2.5.1: + resolution: {integrity: sha512-UM4nTLWzQiDBseVxUGxN0wJzIk0UU89Qi7pKXz9qISo+lhviJikTuikBsK/oFRlpvYHvSdz0TVoLyQ+sEpYwxA==} + + strtok3@10.6.2: + resolution: {integrity: sha512-BkdixFFUt7r7LsX6aGNPVyYMLjW+M1USLlKPNbZsrZEmLFh5tGqhdfckKo6xgsZIJqdDD0CZGkeCJJwNWQIKQA==} + engines: {node: '>=18'} + + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + + tar-fs@2.1.5: + resolution: {integrity: sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + token-types@6.1.2: + resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} + engines: {node: '>=14.16'} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + turndown@7.2.4: + resolution: {integrity: sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==} + engines: {node: '>=18', npm: '>=9'} + + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uint8array-extras@1.6.0: + resolution: {integrity: sha512-8iAasVS4wUx0gPLjH8Xtz2PeDzTSiy8QiLGu2DT3X5GU+egFEQhpnbtkehbAwjvDcxIERmCYcysiODFmE3Ud0Q==} + engines: {node: '>=18'} + + undici@7.29.1: + resolution: {integrity: sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==} + engines: {node: '>=20.18.1'} + + unenv@2.0.0-rc.24: + resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.3.4: + resolution: {integrity: sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + verkit@0.5.0: + resolution: {integrity: sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==} + engines: {node: '>=18.12.0'} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@7.3.5: + resolution: {integrity: sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + which-typed-array@1.1.24: + resolution: {integrity: sha512-wk4Mf4pR5mRP7eYuuTBCIQ9d0ud2Fv2jRLQpfgnRjbOxAFHmjKFValgTpitVKzJJS8ajnYQV2Du1SZ8j6b/EUQ==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + workerd@1.20260714.1: + resolution: {integrity: sha512-oIbQzfdyl9UQUnG6XLegcSq0Mgt/7WKDbFOoqGgOWCS+/fhyGB460uKEgdAQQ9RHCO/ttcNCX/KiMIQzdoeu3Q==} + engines: {node: '>=16'} + hasBin: true + + workers-ai-provider@4.0.0: + resolution: {integrity: sha512-FkhwMP1EP/MKXR8Jv1o7wLVKfTqu0h/PUaEmhZ7gyDiioib5Wsh3oPAKhG+7+SWfU3roTDHaEWlJpkJjpXu+fQ==} + peerDependencies: + '@ai-sdk/anthropic': ^4.0.0 + '@ai-sdk/google': ^4.0.0 + '@ai-sdk/openai': ^4.0.0 + '@ai-sdk/provider': ^4.0.0 + ai: ^7.0.0 + peerDependenciesMeta: + '@ai-sdk/anthropic': + optional: true + '@ai-sdk/google': + optional: true + '@ai-sdk/openai': + optional: true + + wrangler@4.112.0: + resolution: {integrity: sha512-5H+XUD0TySCv1LuktFHDIEOkboH2nTfQs+35L+USt3MtntjDTMVIJprLgQcL2WBjulOyjxpd1vyTiSTJVW5MjQ==} + engines: {node: '>=22.0.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^5.20260714.1 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-naming@0.3.0: + resolution: {integrity: sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==} + engines: {node: '>=16.0.0'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaml@2.9.1: + resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@18.2.0: + resolution: {integrity: sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + youch-core@0.3.3: + resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} + + youch@4.1.0-beta.10: + resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} + + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: ^3.25.28 || ^4 + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@ai-sdk/anthropic@4.0.84(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 4.0.31 + '@ai-sdk/provider-utils': 5.0.64(zod@4.3.6) + zod: 4.3.6 + + '@ai-sdk/gateway@4.0.111(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 4.0.27 + '@ai-sdk/provider-utils': 5.0.59(zod@4.3.6) + '@vercel/oidc': 3.2.0 + zod: 4.3.6 + + '@ai-sdk/openai@4.0.93(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 4.0.27 + '@ai-sdk/provider-utils': 5.0.59(zod@4.3.6) + zod: 4.3.6 + + '@ai-sdk/provider-utils@5.0.59(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 4.0.27 + '@standard-schema/spec': 1.1.0 + '@workflow/serde': 4.1.0 + eventsource-parser: 3.1.1 + undici: 7.29.1 + zod: 4.3.6 + + '@ai-sdk/provider-utils@5.0.64(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 4.0.31 + '@standard-schema/spec': 1.1.0 + '@workflow/serde': 4.1.0 + eventsource-parser: 3.1.1 + undici: 7.29.1 + zod: 4.3.6 + + '@ai-sdk/provider@4.0.27': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/provider@4.0.31': + dependencies: + json-schema: 0.4.0 + + '@babel/code-frame@8.0.6': + dependencies: + '@babel/helper-validator-identifier': 8.0.6 + js-tokens: 10.0.0 + + '@babel/compat-data@8.0.5': {} + + '@babel/core@8.0.7': + dependencies: + '@babel/code-frame': 8.0.6 + '@babel/generator': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 + '@babel/helpers': 8.0.7 + '@babel/parser': 8.0.7 + '@babel/template': 8.0.0 + '@babel/traverse': 8.0.7 + '@babel/types': 8.0.6 + '@types/gensync': 1.0.5 + convert-source-map: 2.0.0 + empathic: 2.1.0 + gensync: 1.0.0-beta.2 + import-meta-resolve: 4.2.0 + json5: 2.2.3 + obug: 3.0.0 + verkit: 0.5.0 + + '@babel/generator@8.0.6': + dependencies: + '@babel/parser': 8.0.7 + '@babel/types': 8.0.6 + '@jridgewell/gen-mapping': 0.4.0-beta.0 + '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@8.0.0': + dependencies: + '@babel/types': 8.0.6 + + '@babel/helper-compilation-targets@8.0.7': + dependencies: + '@babel/compat-data': 8.0.5 + '@babel/helper-validator-option': 8.0.0 + browserslist: 4.29.4 + flru: 1.0.2 + verkit: 0.5.0 + + '@babel/helper-create-class-features-plugin@8.0.7(@babel/core@8.0.7)': + dependencies: + '@babel/core': 8.0.7 + '@babel/helper-annotate-as-pure': 8.0.0 + '@babel/helper-member-expression-to-functions': 8.0.5 + '@babel/helper-optimise-call-expression': 8.0.0 + '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.7) + '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 + '@babel/traverse': 8.0.7 + verkit: 0.5.0 + + '@babel/helper-globals@8.0.6': {} + + '@babel/helper-member-expression-to-functions@8.0.5': + dependencies: + '@babel/traverse': 8.0.7 + '@babel/types': 8.0.6 + + '@babel/helper-optimise-call-expression@8.0.0': + dependencies: + '@babel/types': 8.0.6 + + '@babel/helper-plugin-utils@8.0.1(@babel/core@8.0.7)': + dependencies: + '@babel/core': 8.0.7 + + '@babel/helper-replace-supers@8.0.1(@babel/core@8.0.7)': + dependencies: + '@babel/core': 8.0.7 + '@babel/helper-member-expression-to-functions': 8.0.5 + '@babel/helper-optimise-call-expression': 8.0.0 + '@babel/traverse': 8.0.7 + + '@babel/helper-skip-transparent-expression-wrappers@8.0.0': + dependencies: + '@babel/traverse': 8.0.7 + '@babel/types': 8.0.6 + + '@babel/helper-string-parser@8.0.6': {} + + '@babel/helper-validator-identifier@8.0.6': {} + + '@babel/helper-validator-option@8.0.0': {} + + '@babel/helpers@8.0.7': + dependencies: + '@babel/template': 8.0.0 + '@babel/types': 8.0.6 + + '@babel/parser@8.0.7': + dependencies: + '@babel/types': 8.0.6 + + '@babel/plugin-proposal-decorators@8.0.2(@babel/core@8.0.7)': + dependencies: + '@babel/core': 8.0.7 + '@babel/helper-create-class-features-plugin': 8.0.7(@babel/core@8.0.7) + '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) + '@babel/plugin-syntax-decorators': 8.0.1(@babel/core@8.0.7) + + '@babel/plugin-syntax-decorators@8.0.1(@babel/core@8.0.7)': + dependencies: + '@babel/core': 8.0.7 + '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) + + '@babel/runtime-corejs3@7.29.10': + dependencies: + core-js-pure: 3.51.0 + + '@babel/runtime@7.29.10': {} + + '@babel/template@8.0.0': + dependencies: + '@babel/code-frame': 8.0.6 + '@babel/parser': 8.0.7 + '@babel/types': 8.0.6 + + '@babel/traverse@8.0.7': + dependencies: + '@babel/code-frame': 8.0.6 + '@babel/generator': 8.0.6 + '@babel/helper-globals': 8.0.6 + '@babel/parser': 8.0.7 + '@babel/template': 8.0.0 + '@babel/types': 8.0.6 + obug: 3.0.0 + + '@babel/types@8.0.6': + dependencies: + '@babel/helper-string-parser': 8.0.6 + '@babel/helper-validator-identifier': 8.0.6 + + '@borewit/text-codec@0.2.2': {} + + '@cfworker/json-schema@4.1.1': {} + + '@chat-adapter/catalog@4.43.0': {} + + '@cloudflare/codemode@0.4.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6)': + dependencies: + '@types/json-schema': 7.0.15 + acorn: 8.19.0 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + zod: 4.3.6 + + '@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6)': + dependencies: + '@types/json-schema': 7.0.15 + acorn: 8.19.0 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + zod: 4.3.6 + + '@cloudflare/kv-asset-handler@0.5.0': {} + + '@cloudflare/shell@0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6)': + dependencies: + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + isomorphic-git: 1.44.3 + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - ai + - zod + + '@cloudflare/think@0.15.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.93(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + aywson: 0.0.16 + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + create-think: 0.1.1 + just-bash: 3.6.0 + smol-toml: 1.9.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) + yargs: 18.2.0 + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.15.1(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.93(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + aywson: 0.0.16 + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + create-think: 0.1.1 + just-bash: 3.6.0 + smol-toml: 1.9.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) + yargs: 18.2.0 + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.16.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.93(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.17.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.93(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.18.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.93(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.19.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.93(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.20.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.93(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.20.1(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.93(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/think@0.20.2(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.93(zod@4.3.6) + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) + zod: 4.3.6 + optionalDependencies: + react: 19.3.1 + transitivePeerDependencies: + - '@ai-sdk/google' + - '@ai-sdk/provider' + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - supports-color + - workflow + + '@cloudflare/unenv-preset@2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260714.1)': + dependencies: + unenv: 2.0.0-rc.24 + optionalDependencies: + workerd: 1.20260714.1 + + '@cloudflare/vite-plugin@1.45.1(vite@7.3.5(yaml@2.9.1))(wrangler@4.112.0(@cloudflare/workers-types@5.20261019.1))': + dependencies: + '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260714.1) + miniflare: 4.20260714.0 + unenv: 2.0.0-rc.24 + vite: 7.3.5(yaml@2.9.1) + workerd: 1.20260714.1 + wrangler: 4.112.0(@cloudflare/workers-types@5.20261019.1) + ws: 8.21.0 + transitivePeerDependencies: + - '@types/node' + - bufferutil + - utf-8-validate + + '@cloudflare/workerd-darwin-64@1.20260714.1': + optional: true + + '@cloudflare/workerd-darwin-arm64@1.20260714.1': + optional: true + + '@cloudflare/workerd-linux-64@1.20260714.1': + optional: true + + '@cloudflare/workerd-linux-arm64@1.20260714.1': + optional: true + + '@cloudflare/workerd-windows-64@1.20260714.1': + optional: true + + '@cloudflare/workers-types@5.20261019.1': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@emnapi/runtime@1.11.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.28.1': + optional: true + + '@esbuild/aix-ppc64@0.28.2': + optional: true + + '@esbuild/android-arm64@0.28.1': + optional: true + + '@esbuild/android-arm64@0.28.2': + optional: true + + '@esbuild/android-arm@0.28.1': + optional: true + + '@esbuild/android-arm@0.28.2': + optional: true + + '@esbuild/android-x64@0.28.1': + optional: true + + '@esbuild/android-x64@0.28.2': + optional: true + + '@esbuild/darwin-arm64@0.28.1': + optional: true + + '@esbuild/darwin-arm64@0.28.2': + optional: true + + '@esbuild/darwin-x64@0.28.1': + optional: true + + '@esbuild/darwin-x64@0.28.2': + optional: true + + '@esbuild/freebsd-arm64@0.28.1': + optional: true + + '@esbuild/freebsd-arm64@0.28.2': + optional: true + + '@esbuild/freebsd-x64@0.28.1': + optional: true + + '@esbuild/freebsd-x64@0.28.2': + optional: true + + '@esbuild/linux-arm64@0.28.1': + optional: true + + '@esbuild/linux-arm64@0.28.2': + optional: true + + '@esbuild/linux-arm@0.28.1': + optional: true + + '@esbuild/linux-arm@0.28.2': + optional: true + + '@esbuild/linux-ia32@0.28.1': + optional: true + + '@esbuild/linux-ia32@0.28.2': + optional: true + + '@esbuild/linux-loong64@0.28.1': + optional: true + + '@esbuild/linux-loong64@0.28.2': + optional: true + + '@esbuild/linux-mips64el@0.28.1': + optional: true + + '@esbuild/linux-mips64el@0.28.2': + optional: true + + '@esbuild/linux-ppc64@0.28.1': + optional: true + + '@esbuild/linux-ppc64@0.28.2': + optional: true + + '@esbuild/linux-riscv64@0.28.1': + optional: true + + '@esbuild/linux-riscv64@0.28.2': + optional: true + + '@esbuild/linux-s390x@0.28.1': + optional: true + + '@esbuild/linux-s390x@0.28.2': + optional: true + + '@esbuild/linux-x64@0.28.1': + optional: true + + '@esbuild/linux-x64@0.28.2': + optional: true + + '@esbuild/netbsd-arm64@0.28.1': + optional: true + + '@esbuild/netbsd-arm64@0.28.2': + optional: true + + '@esbuild/netbsd-x64@0.28.1': + optional: true + + '@esbuild/netbsd-x64@0.28.2': + optional: true + + '@esbuild/openbsd-arm64@0.28.1': + optional: true + + '@esbuild/openbsd-arm64@0.28.2': + optional: true + + '@esbuild/openbsd-x64@0.28.1': + optional: true + + '@esbuild/openbsd-x64@0.28.2': + optional: true + + '@esbuild/openharmony-arm64@0.28.1': + optional: true + + '@esbuild/openharmony-arm64@0.28.2': + optional: true + + '@esbuild/sunos-x64@0.28.1': + optional: true + + '@esbuild/sunos-x64@0.28.2': + optional: true + + '@esbuild/win32-arm64@0.28.1': + optional: true + + '@esbuild/win32-arm64@0.28.2': + optional: true + + '@esbuild/win32-ia32@0.28.1': + optional: true + + '@esbuild/win32-ia32@0.28.2': + optional: true + + '@esbuild/win32-x64@0.28.1': + optional: true + + '@esbuild/win32-x64@0.28.2': + optional: true + + '@hono/node-server@2.1.5(hono@4.13.7)': + dependencies: + hono: 4.13.7 + + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.3.4 + optional: true + + '@img/sharp-darwin-x64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.3.4 + optional: true + + '@img/sharp-freebsd-wasm32@0.35.5': + dependencies: + '@img/sharp-wasm32': 0.35.5 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.3.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.3.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.3.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.3.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.3.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.3.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.3.4': + optional: true + + '@img/sharp-linux-arm64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.3.4 + optional: true + + '@img/sharp-linux-arm@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.3.4 + optional: true + + '@img/sharp-linux-ppc64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.3.4 + optional: true + + '@img/sharp-linux-riscv64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.3.4 + optional: true + + '@img/sharp-linux-s390x@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.3.4 + optional: true + + '@img/sharp-linux-x64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.3.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.3.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.35.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.3.4 + optional: true + + '@img/sharp-wasm32@0.35.5': + dependencies: + '@emnapi/runtime': 1.11.3 + optional: true + + '@img/sharp-webcontainers-wasm32@0.35.5': + dependencies: + '@img/sharp-wasm32': 0.35.5 + optional: true + + '@img/sharp-win32-arm64@0.35.5': + optional: true + + '@img/sharp-win32-ia32@0.35.5': + optional: true + + '@img/sharp-win32-x64@0.35.5': + optional: true + + '@jridgewell/gen-mapping@0.4.0-beta.0': + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.6.0': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@mixmark-io/domino@2.2.0': {} + + '@modelcontextprotocol/client@2.0.0': + dependencies: + '@modelcontextprotocol/core': 2.0.0 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.1.1 + jose: 6.2.13 + pkce-challenge: 5.0.1 + zod: 4.3.6 + + '@modelcontextprotocol/core@2.0.0': + dependencies: + zod: 4.3.6 + + '@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6)': + dependencies: + '@hono/node-server': 2.1.5(hono@4.13.7) + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.1.1 + express: 5.3.0 + express-rate-limit: 8.7.1(express@5.3.0) + hono: 4.13.7 + jose: 6.2.13 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.3.6 + zod-to-json-schema: 3.25.2(zod@4.3.6) + optionalDependencies: + '@cfworker/json-schema': 4.1.1 + transitivePeerDependencies: + - supports-color + + '@modelcontextprotocol/server@2.0.0': + dependencies: + '@modelcontextprotocol/core': 2.0.0 + zod: 4.3.6 + + '@mongodb-js/zstd@7.0.0': + dependencies: + node-addon-api: 8.9.2 + prebuild-install: 7.1.3 + optional: true + + '@napi-rs/lzma-linux-x64-gnu@1.5.1': + optional: true + + '@nodable/entities@3.1.0': {} + + '@oxc-project/types@0.154.0': {} + + '@poppinss/colors@4.1.6': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.6.5': + dependencies: + '@poppinss/colors': 4.1.6 + '@sindresorhus/is': 7.2.0 + supports-color: 10.2.2 + + '@poppinss/exception@1.2.3': {} + + '@rolldown/binding-android-arm-eabi@1.2.14': + optional: true + + '@rolldown/binding-android-arm64@1.2.14': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.14': + optional: true + + '@rolldown/binding-darwin-x64@1.2.14': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.14': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.14': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.14': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.14': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.14': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.14': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.14': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.14': + optional: true + + '@rolldown/binding-openharmony-arm64@1.2.14': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.14': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.14': + optional: true + + '@rolldown/plugin-babel@0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))': + dependencies: + '@babel/core': 8.0.7 + picomatch: 4.0.7 + rolldown: 1.2.14 + optionalDependencies: + '@babel/runtime': 7.29.10 + vite: 7.3.5(yaml@2.9.1) + + '@rolldown/pluginutils@1.0.1': {} + + '@rollup/rollup-android-arm-eabi@4.64.12': + optional: true + + '@rollup/rollup-android-arm64@4.64.12': + optional: true + + '@rollup/rollup-darwin-arm64@4.64.12': + optional: true + + '@rollup/rollup-darwin-x64@4.64.12': + optional: true + + '@rollup/rollup-freebsd-arm64@4.64.12': + optional: true + + '@rollup/rollup-freebsd-x64@4.64.12': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.64.12': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.64.12': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.64.12': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.64.12': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.64.12': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.64.12': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.64.12': + optional: true + + '@rollup/rollup-linux-x64-musl@4.64.12': + optional: true + + '@rollup/rollup-openbsd-x64@4.64.12': + optional: true + + '@rollup/rollup-openharmony-arm64@4.64.12': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.64.12': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.64.12': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.64.12': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.64.12': + optional: true + + '@sindresorhus/is@7.2.0': {} + + '@speed-highlight/core@1.2.24': {} + + '@standard-schema/spec@1.1.0': {} + + '@tokenizer/inflate@0.4.1': + dependencies: + debug: 4.4.3 + token-types: 6.1.2 + transitivePeerDependencies: + - supports-color + + '@tokenizer/token@0.3.0': {} + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree@1.0.9': {} + + '@types/gensync@1.0.5': {} + + '@types/jsesc@2.5.1': {} + + '@types/json-schema@7.0.15': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/ms@2.1.0': {} + + '@types/unist@3.0.3': {} + + '@vercel/oidc@3.2.0': {} + + '@workflow/serde@4.1.0': {} + + '@workflow/serde@4.1.0-beta.2': {} + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.1.0 + + acorn@8.19.0: {} + + agents@0.18.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/workers-types@5.20261019.1)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): + dependencies: + '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) + '@cfworker/json-schema': 4.1.1 + '@cloudflare/codemode': 0.4.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + '@rolldown/plugin-babel': 0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1)) + cron-schedule: 6.0.0 + esbuild: 0.28.2 + mimetext: 3.0.28 + nanoid: 5.1.16 + partyserver: 0.5.10(@cloudflare/workers-types@5.20261019.1) + partysocket: 1.3.0(react@19.3.1) + react: 19.3.1 + yaml: 2.9.1 + yargs: 18.2.0 + zod: 4.3.6 + optionalDependencies: + ai: 7.0.138(zod@4.3.6) + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@babel/core' + - '@babel/plugin-transform-runtime' + - '@babel/runtime' + - '@cloudflare/workers-types' + - rolldown + - supports-color + + agents@0.22.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): + dependencies: + '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) + '@cfworker/json-schema': 4.1.1 + '@modelcontextprotocol/client': 2.0.0 + '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + '@modelcontextprotocol/server': 2.0.0 + '@rolldown/plugin-babel': 0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1)) + cron-schedule: 6.0.0 + esbuild: 0.28.2 + mimetext: 3.0.28 + nanoid: 5.1.16 + partysocket: 1.3.0(react@19.3.1) + yaml: 2.9.1 + zod: 4.3.6 + optionalDependencies: + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + react: 19.3.1 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@babel/core' + - '@babel/plugin-transform-runtime' + - '@babel/runtime' + - rolldown + + agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): + dependencies: + '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) + '@cfworker/json-schema': 4.1.1 + '@modelcontextprotocol/client': 2.0.0 + '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) + '@modelcontextprotocol/server': 2.0.0 + '@rolldown/plugin-babel': 0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1)) + capnweb: 0.12.0 + cron-schedule: 6.0.0 + esbuild: 0.28.2 + mimetext: 3.0.28 + nanoid: 5.1.16 + partysocket: 1.3.0(react@19.3.1) + postal-mime: 2.7.6 + yaml: 2.9.1 + zod: 4.3.6 + optionalDependencies: + '@ai-sdk/provider': 4.0.31 + '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + ai: 7.0.138(zod@4.3.6) + chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) + just-bash: 3.6.0 + react: 19.3.1 + vite: 7.3.5(yaml@2.9.1) + transitivePeerDependencies: + - '@babel/core' + - '@babel/plugin-transform-runtime' + - '@babel/runtime' + - rolldown + + ai@7.0.138(zod@4.3.6): + dependencies: + '@ai-sdk/gateway': 4.0.111(zod@4.3.6) + '@ai-sdk/provider': 4.0.27 + '@ai-sdk/provider-utils': 5.0.59(zod@4.3.6) + zod: 4.3.6 + + ajv-formats@3.0.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.8 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-regex@6.4.0: {} + + ansi-styles@6.2.3: {} + + anynum@1.0.1: {} + + async-lock@1.4.1: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + aywson@0.0.16: + dependencies: + chalk: 5.6.2 + jsonc-parser: 3.3.1 + + bail@2.0.2: {} + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.11.30: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + optional: true + + blake3-wasm@2.1.5: {} + + body-parser@2.3.0: + dependencies: + bytes: 3.1.2 + content-type: 2.1.0 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + on-finished: 2.4.1 + qs: 6.16.1 + raw-body: 3.0.2 + type-is: 2.1.0 + transitivePeerDependencies: + - supports-color + + browserslist@4.29.4: + dependencies: + baseline-browser-mapping: 2.11.30 + caniuse-lite: 1.0.30001817 + electron-to-chromium: 1.5.460 + node-releases: 2.0.59 + update-browserslist-db: 1.3.4(browserslist@4.29.4) + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + optional: true + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bytes@3.1.2: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + caniuse-lite@1.0.30001817: {} + + capnweb@0.12.0: {} + + ccount@2.0.1: {} + + chalk@5.6.2: {} + + character-entities@2.0.2: {} + + chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6): + dependencies: + '@chat-adapter/catalog': 4.43.0 + '@workflow/serde': 4.1.0-beta.2 + mdast-util-to-string: 4.0.0 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + remend: 1.4.0 + unified: 11.0.5 + optionalDependencies: + ai: 7.0.138(zod@4.3.6) + zod: 4.3.6 + transitivePeerDependencies: + - supports-color + + chownr@1.1.4: + optional: true + + clean-git-ref@2.0.1: {} + + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + + commander@6.2.1: {} + + content-disposition@2.0.1: {} + + content-type@1.0.5: {} + + content-type@2.1.0: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cookie@1.1.1: {} + + core-js-pure@3.51.0: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + crc-32@1.2.2: {} + + create-think@0.1.1: {} + + cron-schedule@6.0.0: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + dc-browser@1.0.4: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-extend@0.6.0: + optional: true + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + depd@2.0.0: {} + + dequal@2.0.3: {} + + detect-libc@2.1.2: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff3@0.0.3: {} + + diff@8.0.4: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.460: {} + + emoji-regex@10.6.0: {} + + empathic@2.1.0: {} + + encodeurl@2.0.0: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + optional: true + + error-stack-parser-es@1.0.5: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + esbuild@0.28.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 + + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@5.0.0: {} + + etag@1.8.1: {} + + event-target-polyfill@0.0.4: {} + + event-target-shim@5.0.1: {} + + events@3.3.0: {} + + eventsource-parser@3.1.1: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.1.1 + + expand-template@2.0.3: + optional: true + + express-rate-limit@8.7.1(express@5.3.0): + dependencies: + debug: 4.4.3 + express: 5.3.0 + ip-address: 10.7.1 + transitivePeerDependencies: + - supports-color + + express@5.3.0: + dependencies: + accepts: 2.0.0 + body-parser: 2.3.0 + content-disposition: 2.0.1 + content-type: 2.1.0 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.8 + qs: 6.16.1 + range-parser: 1.3.0 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.1.0 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-uri@3.1.8: {} + + fast-xml-builder@1.3.1: + dependencies: + path-expression-matcher: 1.6.2 + xml-naming: 0.3.0 + + fast-xml-parser@5.11.2: + dependencies: + '@nodable/entities': 3.1.0 + fast-xml-builder: 1.3.1 + is-unsafe: 2.0.2 + path-expression-matcher: 1.6.2 + strnum: 2.5.1 + xml-naming: 0.3.0 + + fdir@6.5.0(picomatch@4.0.7): + optionalDependencies: + picomatch: 4.0.7 + + file-type@21.3.4: + dependencies: + '@tokenizer/inflate': 0.4.1 + strtok3: 10.6.2 + token-types: 6.1.2 + uint8array-extras: 1.6.0 + transitivePeerDependencies: + - supports-color + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + flru@1.0.2: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + fs-constants@1.0.0: + optional: true + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.7.0: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + github-from-package@0.0.0: + optional: true + + gopd@1.2.0: {} + + guarded-fetch@0.1.3: + dependencies: + ipaddr.js: 2.2.0 + undici: 7.29.1 + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + hono@4.13.7: {} + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + iconv-lite@0.7.3: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + import-meta-resolve@4.2.0: {} + + inherits@2.0.4: {} + + ini@1.3.8: + optional: true + + ini@6.0.0: {} + + ip-address@10.7.1: {} + + ipaddr.js@1.9.1: {} + + ipaddr.js@2.2.0: {} + + is-callable@1.2.7: {} + + is-plain-obj@4.1.0: {} + + is-promise@4.0.0: {} + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.24 + + is-unsafe@2.0.2: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isomorphic-git@1.44.3: + dependencies: + async-lock: 1.4.1 + clean-git-ref: 2.0.1 + crc-32: 1.2.2 + diff3: 0.0.3 + ignore: 5.3.2 + minimisted: 2.0.1 + pako: 1.0.11 + pify: 4.0.1 + readable-stream: 4.8.0 + sha.js: 2.4.12 + simple-get: 4.0.1 + + jose@6.2.13: {} + + js-base64@3.9.4: {} + + js-tokens@10.0.0: {} + + jsesc@3.1.0: {} + + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + + json-schema@0.4.0: {} + + json5@2.2.3: {} + + jsonc-parser@3.3.1: {} + + just-bash@3.6.0: + dependencies: + diff: 8.0.4 + fast-xml-parser: 5.11.2 + file-type: 21.3.4 + guarded-fetch: 0.1.3 + ini: 6.0.0 + modern-tar: 0.7.7 + papaparse: 5.7.0 + re2js: 1.3.3 + run: 2.1.3(typescript@5.9.3) + seek-bzip: 2.0.0 + smol-toml: 1.9.0 + sprintf-js: 1.1.3 + sql.js: 1.15.1 + turndown: 7.2.4 + typescript: 5.9.3 + yaml: 2.9.1 + optionalDependencies: + '@mongodb-js/zstd': 7.0.0 + node-liblzma: 2.2.0 + transitivePeerDependencies: + - supports-color + + kleur@4.1.5: {} + + longest-streak@3.1.0: {} + + markdown-table@3.0.4: {} + + math-intrinsics@1.1.0: {} + + mdast-util-find-and-replace@3.0.3: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.3 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.3 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.1.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.1.0 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.1 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.2.0 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-markdown@2.2.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-character: 2.1.1 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + media-typer@1.1.1: {} + + merge-descriptors@2.0.0: {} + + micromark-core-commonmark@2.0.4: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.1.0 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-edit-map: 1.0.0 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.4 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-table@2.1.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.3 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.2 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-space@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.3 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-edit-map@1.0.0: + dependencies: + micromark-util-types: 2.0.3 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.3 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.3: {} + + micromark@4.0.3: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.4 + micromark-factory-space: 2.1.0 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-edit-map: 1.0.0 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + transitivePeerDependencies: + - supports-color + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mimetext@3.0.28: + dependencies: + '@babel/runtime': 7.29.10 + '@babel/runtime-corejs3': 7.29.10 + js-base64: 3.9.4 + mime-types: 2.1.35 + + mimic-response@3.1.0: {} + + miniflare@4.20260714.0: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + sharp: 0.35.5 + undici: 7.29.1 + workerd: 1.20260714.1 + ws: 8.21.0 + youch: 4.1.0-beta.10 + transitivePeerDependencies: + - '@types/node' + - bufferutil + - utf-8-validate + + minimist@1.2.8: {} + + minimisted@2.0.1: + dependencies: + minimist: 1.2.8 + + mkdirp-classic@0.5.3: + optional: true + + modern-tar@0.7.7: {} + + ms@2.1.3: {} + + nanoid@3.3.20: {} + + nanoid@5.1.16: {} + + napi-build-utils@2.0.0: + optional: true + + negotiator@1.1.0: + dependencies: + content-type: 2.1.0 + + node-abi@3.99.0: + dependencies: + semver: 7.8.5 + optional: true + + node-addon-api@8.9.2: + optional: true + + node-gyp-build@4.8.4: + optional: true + + node-liblzma@2.2.0: + dependencies: + node-addon-api: 8.9.2 + node-gyp-build: 4.8.4 + optional: true + + node-releases@2.0.59: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + obug@3.0.0: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + pako@1.0.11: {} + + papaparse@5.7.0: {} + + parseurl@1.3.3: {} + + partyserver@0.5.10(@cloudflare/workers-types@5.20261019.1): + dependencies: + '@cloudflare/workers-types': 5.20261019.1 + nanoid: 5.1.16 + + partysocket@1.3.0(react@19.3.1): + dependencies: + event-target-polyfill: 0.0.4 + optionalDependencies: + react: 19.3.1 + + path-expression-matcher@1.6.2: {} + + path-key@3.1.1: {} + + path-to-regexp@6.3.0: {} + + path-to-regexp@8.4.2: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.7: {} + + pify@4.0.1: {} + + pkce-challenge@5.0.1: {} + + possible-typed-array-names@1.1.0: {} + + postal-mime@2.7.6: {} + + postcss@8.5.31: + dependencies: + nanoid: 3.3.20 + picocolors: 1.1.1 + source-map-js: 1.2.2 + + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.99.0 + pump: 3.0.4 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.5 + tunnel-agent: 0.6.0 + optional: true + + process@0.11.10: {} + + proxy-addr@2.0.8: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + optional: true + + qs@6.16.1: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + + range-parser@1.3.0: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + unpipe: 1.0.0 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + optional: true + + re2js@1.3.3: {} + + react@19.3.1: {} + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + optional: true + + readable-stream@4.8.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.1.0 + micromark-util-types: 2.0.3 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.2.0 + unified: 11.0.5 + + remend@1.4.0: {} + + require-from-string@2.0.2: {} + + rolldown@1.2.14: + dependencies: + '@oxc-project/types': 0.154.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm-eabi': 1.2.14 + '@rolldown/binding-android-arm64': 1.2.14 + '@rolldown/binding-darwin-arm64': 1.2.14 + '@rolldown/binding-darwin-x64': 1.2.14 + '@rolldown/binding-freebsd-x64': 1.2.14 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.14 + '@rolldown/binding-linux-arm64-gnu': 1.2.14 + '@rolldown/binding-linux-arm64-musl': 1.2.14 + '@rolldown/binding-linux-ppc64-gnu': 1.2.14 + '@rolldown/binding-linux-s390x-gnu': 1.2.14 + '@rolldown/binding-linux-x64-gnu': 1.2.14 + '@rolldown/binding-linux-x64-musl': 1.2.14 + '@rolldown/binding-openharmony-arm64': 1.2.14 + '@rolldown/binding-win32-arm64-msvc': 1.2.14 + '@rolldown/binding-win32-x64-msvc': 1.2.14 + + rollup@4.64.12: + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + '@napi-rs/lzma-linux-x64-gnu': 1.5.1 + '@rollup/rollup-android-arm-eabi': 4.64.12 + '@rollup/rollup-android-arm64': 4.64.12 + '@rollup/rollup-darwin-arm64': 4.64.12 + '@rollup/rollup-darwin-x64': 4.64.12 + '@rollup/rollup-freebsd-arm64': 4.64.12 + '@rollup/rollup-freebsd-x64': 4.64.12 + '@rollup/rollup-linux-arm-gnueabihf': 4.64.12 + '@rollup/rollup-linux-arm-musleabihf': 4.64.12 + '@rollup/rollup-linux-arm64-gnu': 4.64.12 + '@rollup/rollup-linux-arm64-musl': 4.64.12 + '@rollup/rollup-linux-loong64-gnu': 4.64.12 + '@rollup/rollup-linux-loong64-musl': 4.64.12 + '@rollup/rollup-linux-ppc64-gnu': 4.64.12 + '@rollup/rollup-linux-ppc64-musl': 4.64.12 + '@rollup/rollup-linux-riscv64-gnu': 4.64.12 + '@rollup/rollup-linux-riscv64-musl': 4.64.12 + '@rollup/rollup-linux-s390x-gnu': 4.64.12 + '@rollup/rollup-linux-x64-gnu': 4.64.12 + '@rollup/rollup-linux-x64-musl': 4.64.12 + '@rollup/rollup-openbsd-x64': 4.64.12 + '@rollup/rollup-openharmony-arm64': 4.64.12 + '@rollup/rollup-win32-arm64-msvc': 4.64.12 + '@rollup/rollup-win32-ia32-msvc': 4.64.12 + '@rollup/rollup-win32-x64-gnu': 4.64.12 + '@rollup/rollup-win32-x64-msvc': 4.64.12 + fsevents: 2.3.3 + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.4.2 + transitivePeerDependencies: + - supports-color + + run@2.1.3(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + seek-bzip@2.0.0: + dependencies: + commander: 6.2.1 + + semver@7.8.5: {} + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.3.0 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + sha.js@2.4.12: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + sharp@0.35.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.35.5 + '@img/sharp-darwin-x64': 0.35.5 + '@img/sharp-freebsd-wasm32': 0.35.5 + '@img/sharp-libvips-darwin-arm64': 1.3.4 + '@img/sharp-libvips-darwin-x64': 1.3.4 + '@img/sharp-libvips-linux-arm': 1.3.4 + '@img/sharp-libvips-linux-arm64': 1.3.4 + '@img/sharp-libvips-linux-ppc64': 1.3.4 + '@img/sharp-libvips-linux-riscv64': 1.3.4 + '@img/sharp-libvips-linux-s390x': 1.3.4 + '@img/sharp-libvips-linux-x64': 1.3.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.4 + '@img/sharp-libvips-linuxmusl-x64': 1.3.4 + '@img/sharp-linux-arm': 0.35.5 + '@img/sharp-linux-arm64': 0.35.5 + '@img/sharp-linux-ppc64': 0.35.5 + '@img/sharp-linux-riscv64': 0.35.5 + '@img/sharp-linux-s390x': 0.35.5 + '@img/sharp-linux-x64': 0.35.5 + '@img/sharp-linuxmusl-arm64': 0.35.5 + '@img/sharp-linuxmusl-x64': 0.35.5 + '@img/sharp-webcontainers-wasm32': 0.35.5 + '@img/sharp-win32-arm64': 0.35.5 + '@img/sharp-win32-ia32': 0.35.5 + '@img/sharp-win32-x64': 0.35.5 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + + smol-toml@1.9.0: {} + + source-map-js@1.2.2: {} + + sprintf-js@1.1.3: {} + + sql.js@1.15.1: {} + + statuses@2.0.2: {} + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.7.0 + strip-ansi: 7.2.0 + + string-width@8.3.0: + dependencies: + get-east-asian-width: 1.7.0 + strip-ansi: 7.2.0 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.4.0 + + strip-json-comments@2.0.1: + optional: true + + strnum@2.5.1: + dependencies: + anynum: 1.0.1 + + strtok3@10.6.2: + dependencies: + '@tokenizer/token': 0.3.0 + + supports-color@10.2.2: {} + + tar-fs@2.1.5: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.4 + tar-stream: 2.2.0 + optional: true + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + optional: true + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + + toidentifier@1.0.1: {} + + token-types@6.1.2: + dependencies: + '@borewit/text-codec': 0.2.2 + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + + trough@2.2.0: {} + + tslib@2.8.1: + optional: true + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + optional: true + + turndown@7.2.4: + dependencies: + '@mixmark-io/domino': 2.2.0 + + type-is@2.1.0: + dependencies: + content-type: 2.1.0 + media-typer: 1.1.1 + mime-types: 3.0.2 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typescript@5.9.3: {} + + uint8array-extras@1.6.0: {} + + undici@7.29.1: {} + + unenv@2.0.0-rc.24: + dependencies: + pathe: 2.0.3 + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + unpipe@1.0.0: {} + + update-browserslist-db@1.3.4(browserslist@4.29.4): + dependencies: + browserslist: 4.29.4 + escalade: 3.2.0 + picocolors: 1.1.1 + + util-deprecate@1.0.2: + optional: true + + vary@1.1.2: {} + + verkit@0.5.0: {} + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite@7.3.5(yaml@2.9.1): + dependencies: + esbuild: 0.28.2 + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + postcss: 8.5.31 + rollup: 4.64.12 + tinyglobby: 0.2.17 + optionalDependencies: + fsevents: 2.3.3 + yaml: 2.9.1 + + which-typed-array@1.1.24: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + workerd@1.20260714.1: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20260714.1 + '@cloudflare/workerd-darwin-arm64': 1.20260714.1 + '@cloudflare/workerd-linux-64': 1.20260714.1 + '@cloudflare/workerd-linux-arm64': 1.20260714.1 + '@cloudflare/workerd-windows-64': 1.20260714.1 + + workers-ai-provider@4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)): + dependencies: + '@ai-sdk/provider': 4.0.31 + ai: 7.0.138(zod@4.3.6) + optionalDependencies: + '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) + '@ai-sdk/openai': 4.0.93(zod@4.3.6) + + wrangler@4.112.0(@cloudflare/workers-types@5.20261019.1): + dependencies: + '@cloudflare/kv-asset-handler': 0.5.0 + '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260714.1) + blake3-wasm: 2.1.5 + esbuild: 0.28.1 + miniflare: 4.20260714.0 + path-to-regexp: 6.3.0 + unenv: 2.0.0-rc.24 + workerd: 1.20260714.1 + optionalDependencies: + '@cloudflare/workers-types': 5.20261019.1 + fsevents: 2.3.3 + transitivePeerDependencies: + - '@types/node' + - bufferutil + - utf-8-validate + + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + + wrappy@1.0.2: {} + + ws@8.21.0: {} + + xml-naming@0.3.0: {} + + y18n@5.0.8: {} + + yaml@2.9.1: {} + + yargs-parser@22.0.0: {} + + yargs@18.2.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 8.3.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + + youch-core@0.3.3: + dependencies: + '@poppinss/exception': 1.2.3 + error-stack-parser-es: 1.0.5 + + youch@4.1.0-beta.10: + dependencies: + '@poppinss/colors': 4.1.6 + '@poppinss/dumper': 0.6.5 + '@speed-highlight/core': 1.2.24 + cookie: 1.1.1 + youch-core: 0.3.3 + + zod-to-json-schema@3.25.2(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@4.3.6: {} + + zwitch@2.0.4: {} diff --git a/e2e/scripts/build-pr-e2e-links-comment.mjs b/e2e/scripts/build-pr-e2e-links-comment.mjs index 0047d57f5..793dd4377 100644 --- a/e2e/scripts/build-pr-e2e-links-comment.mjs +++ b/e2e/scripts/build-pr-e2e-links-comment.mjs @@ -98,10 +98,21 @@ async function readScenarioConfig(configPath) { `Variant key/label must be non-empty at scenario index ${index}, variant index ${variantIndex} in ${configPath}`, ); } + const variantKeys = variantEntry.variantKeys ?? [variantKey]; + if ( + !Array.isArray(variantKeys) || + variantKeys.length === 0 || + variantKeys.some((key) => typeof key !== "string" || !key.trim()) + ) { + throw new Error( + `Invalid grouped variant keys at scenario index ${index}, variant index ${variantIndex}`, + ); + } return { label: variantLabel, variantKey, + variantKeys: variantKeys.map((key) => key.trim()), }; }) : []; @@ -492,7 +503,7 @@ function buildCommentBody(options) { } const configuredVariantKeys = new Set( - configuredVariants.map((variant) => variant.variantKey), + configuredVariants.flatMap((variant) => variant.variantKeys), ); const evalOnlyVariantKeys = new Set( (scenario.evals ?? []) @@ -502,7 +513,11 @@ function buildCommentBody(options) { for (const variant of configuredVariants) { const observedRunIds = [ - ...(observedVariants.get(variant.variantKey) ?? []), + ...new Set( + variant.variantKeys.flatMap((key) => [ + ...(observedVariants.get(key) ?? []), + ]), + ), ].sort(); pushScenarioRow({ metadataScenario: scenario.metadataScenario, diff --git a/js/src/auto-instrumentations/configs/ai-sdk.ts b/js/src/auto-instrumentations/configs/ai-sdk.ts index c1c42c528..ea2dc5c42 100644 --- a/js/src/auto-instrumentations/configs/ai-sdk.ts +++ b/js/src/auto-instrumentations/configs/ai-sdk.ts @@ -16,6 +16,17 @@ import { * "orchestrion:ai-sdk:generateText" */ export const aiSDKConfigs: InstrumentationConfig[] = [ + // Think needs the synchronous invocation boundary to keep its task open + // until v7's asynchronous telemetry callbacks take over. + { + channelName: aiSDKChannels.streamTextV7.channelName, + module: { + name: "ai", + versionRange: ">=7.0.0 <8.0.0", + filePath: "dist/index.js", + }, + functionQuery: { functionName: "streamText" }, + }, // Older evaluation releases have no telemetry callbacks. Newer versions use // the telemetry dispatcher below, including the renamed decision API. { diff --git a/js/src/auto-instrumentations/configs/cloudflare-think.ts b/js/src/auto-instrumentations/configs/cloudflare-think.ts index 7a6d6bd87..9a1e76753 100644 --- a/js/src/auto-instrumentations/configs/cloudflare-think.ts +++ b/js/src/auto-instrumentations/configs/cloudflare-think.ts @@ -1,7 +1,7 @@ import type { InstrumentationConfig } from "../orchestrion-js"; import { cloudflareThinkChannels } from "../../instrumentation/plugins/cloudflare-think-interceptors"; -const cloudflareThinkVersionRange = ">=0.13.0 <0.14.0"; +const cloudflareThinkVersionRange = ">=0.13.0 <0.21.0"; export const cloudflareThinkConfigs: InstrumentationConfig[] = [ { diff --git a/js/src/instrumentation/plugins/ai-sdk-interceptors.ts b/js/src/instrumentation/plugins/ai-sdk-interceptors.ts index 0c20ff138..5a0427dce 100644 --- a/js/src/instrumentation/plugins/ai-sdk-interceptors.ts +++ b/js/src/instrumentation/plugins/ai-sdk-interceptors.ts @@ -95,6 +95,9 @@ export const aiSDKChannels = defineInterceptor("ai", { >({ channelName: "streamText.sync", }), + streamTextV7: channel<[AISDKCallParams], AISDKResult, AISDKChannelContext>({ + channelName: "streamText.v7", + }), generateObject: channel< [AISDKCallParams], PromiseLike | AISDKStreamResult, diff --git a/js/src/instrumentation/plugins/ai-sdk-plugin.ts b/js/src/instrumentation/plugins/ai-sdk-plugin.ts index d45e0edb4..3a6b868dd 100644 --- a/js/src/instrumentation/plugins/ai-sdk-plugin.ts +++ b/js/src/instrumentation/plugins/ai-sdk-plugin.ts @@ -90,7 +90,7 @@ import { harnessAgentChannels, } from "./ai-sdk-interceptors"; import { extractTokenMetrics } from "./ai-sdk-metrics"; -import { currentCloudflareThinkSpan } from "./cloudflare-think-context"; +import { currentCloudflareThinkRun } from "./cloudflare-think-context"; interface AISDKPluginConfig { /** @@ -304,7 +304,7 @@ export class AISDKPlugin extends BasePlugin { instrumentationName: INSTRUMENTATION_NAMES.AI_SDK, name: "streamText", type: SpanTypeAttribute.FUNCTION, - shouldTrace: () => currentCloudflareThinkSpan() === undefined, + shouldTrace: () => currentCloudflareThinkRun() === undefined, extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths), extractOutput: (result, endEvent) => @@ -339,7 +339,7 @@ export class AISDKPlugin extends BasePlugin { instrumentationName: INSTRUMENTATION_NAMES.AI_SDK, name: "streamText", type: SpanTypeAttribute.FUNCTION, - shouldTrace: () => currentCloudflareThinkSpan() === undefined, + shouldTrace: () => currentCloudflareThinkRun() === undefined, extractInput: ([params], event, span) => prepareAISDKCallInput(params, event, span, denyOutputPaths), patchResult: ({ endEvent, result, span, startTime }) => @@ -1466,7 +1466,7 @@ function interceptAISDKModelStream( ); } -function patchAISDKV7TelemetryDispatcher( +export function patchAISDKV7TelemetryDispatcher( dispatcher: unknown, telemetry: AISDKV7Telemetry, telemetryOptions?: AISDKV7TelemetryOptions, diff --git a/js/src/instrumentation/plugins/cloudflare-think-context.ts b/js/src/instrumentation/plugins/cloudflare-think-context.ts index 74c9fc6dd..8d5d59ec8 100644 --- a/js/src/instrumentation/plugins/cloudflare-think-context.ts +++ b/js/src/instrumentation/plugins/cloudflare-think-context.ts @@ -1,10 +1,23 @@ import { _internalGetGlobalState, type Span } from "../../logger"; -const cloudflareThinkSpans = new Map(); +export type CloudflareThinkRun = { + span: Span; + startTelemetry: ( + input: unknown, + metadata: Record, + ) => boolean; + finishTelemetry: ( + output: unknown, + metrics: Record, + error?: unknown, + ) => void; +}; -export function registerCloudflareThinkSpan(span: Span): void { - if (span.spanId) { - cloudflareThinkSpans.set(span.spanId, span); +const cloudflareThinkSpans = new Map(); + +export function registerCloudflareThinkSpan(run: CloudflareThinkRun): void { + if (run.span.spanId) { + cloudflareThinkSpans.set(run.span.spanId, run); } } @@ -14,7 +27,7 @@ export function unregisterCloudflareThinkSpan(span: Span): void { } } -export function currentCloudflareThinkSpan(): Span | undefined { +export function currentCloudflareThinkRun(): CloudflareThinkRun | undefined { const parentSpanIds = _internalGetGlobalState()?.contextManager.getParentSpanIds()?.spanParents ?? []; diff --git a/js/src/instrumentation/plugins/cloudflare-think-interceptors.ts b/js/src/instrumentation/plugins/cloudflare-think-interceptors.ts index 7b6991b8e..7af2f6464 100644 --- a/js/src/instrumentation/plugins/cloudflare-think-interceptors.ts +++ b/js/src/instrumentation/plugins/cloudflare-think-interceptors.ts @@ -13,7 +13,7 @@ type CloudflareThinkChannelContext = { export const cloudflareThinkChannels = defineInterceptor("@cloudflare/think", { runInferenceLoop: channel< - [CloudflareThinkTurnInput], + [CloudflareThinkTurnInput, historyLeafId?: string | null], PromiseLike, CloudflareThinkChannelContext >({ diff --git a/js/src/instrumentation/plugins/cloudflare-think-plugin.test.ts b/js/src/instrumentation/plugins/cloudflare-think-plugin.test.ts index 240c33df0..7c81c90c0 100644 --- a/js/src/instrumentation/plugins/cloudflare-think-plugin.test.ts +++ b/js/src/instrumentation/plugins/cloudflare-think-plugin.test.ts @@ -4,11 +4,16 @@ import * as ai from "ai"; import { configureNode } from "../../node/config"; import { _exportsForTestingOnly, + currentSpan, initLogger, + withCurrent, type TestBackgroundLogger, } from "../../logger"; import { wrapAISDK } from "../../wrappers/ai-sdk"; import { wrapCloudflareThink } from "../../wrappers/cloudflare-think"; +import { braintrustAISDKTelemetry } from "../../wrappers/ai-sdk/telemetry"; +import { aiSDKChannels } from "./ai-sdk-interceptors"; +import { registry } from "../registry"; import { cloudflareThinkSpanCountForTesting } from "./cloudflare-think-context"; try { @@ -120,6 +125,265 @@ describe("Cloudflare Think instrumentation", () => { }); expect(spans[0].error).toBeDefined(); }); + + it("keeps concurrent AI SDK 7 turns open until telemetry finishes", async () => { + const telemetry = braintrustAISDKTelemetry(); + const starts: (() => void)[] = []; + class Think { + async _runInferenceLoop(input: { body: string }) { + return aiSDKChannels.streamTextV7.invoke( + () => { + // AI SDK 7 starts telemetry asynchronously, after returning its + // result. Preserve that context while letting Think resolve first. + const span = currentSpan(); + starts.push(() => + withCurrent(span, () => + telemetry.onStart({ + callId: input.body, + operationId: "ai.streamText", + modelId: "think-model", + provider: "think-provider", + messages: [{ role: "user", content: input.body }], + }), + ), + ); + return {}; + }, + undefined, + [{}], + {}, + ); + } + } + wrapCloudflareThink({ Think }); + await Promise.all( + ["first", "second"].map((body) => + new Think()._runInferenceLoop({ body }), + ), + ); + expect(cloudflareThinkSpanCountForTesting()).toBe(2); + starts.forEach((start) => start()); + for (const callId of ["second", "first"]) { + telemetry.onLanguageModelCallStart({ callId }); + telemetry.onLanguageModelCallEnd({ + callId, + text: callId, + usage: { inputTokens: 3, outputTokens: 4, totalTokens: 7 }, + }); + telemetry.onToolExecutionStart({ + callId, + toolCall: { toolCallId: callId, toolName: "lookup", input: {} }, + }); + telemetry.onToolExecutionEnd({ + callId, + toolCall: { toolCallId: callId, toolName: "lookup" }, + output: callId, + success: true, + }); + telemetry.onEnd({ + callId, + operationId: "ai.streamText", + text: callId, + totalUsage: { inputTokens: 3, outputTokens: 4, totalTokens: 7 }, + }); + } + const spans = (await backgroundLogger.drain()) as any[]; + expect(spans).toHaveLength(6); + for (const callId of ["first", "second"]) { + const task = spans.find( + (span) => + span.span_attributes?.name === "Think.runTurn" && + span.input?.[0]?.content === callId, + ); + expect(task).toMatchObject({ + output: { role: "assistant", content: callId }, + metadata: { + braintrust: { integration_name: "cloudflare-think" }, + model: "think-model", + provider: "think-provider", + }, + metrics: { prompt_tokens: 3, completion_tokens: 4, tokens: 7 }, + }); + expect( + spans.filter((span) => span.span_parents?.[0] === task.span_id), + ).toHaveLength(2); + } + }); + + it.each(["onError", "onAbort"])( + "releases an AI SDK 7 turn after %s", + async (end) => { + const telemetry = braintrustAISDKTelemetry(); + class Think { + async _runInferenceLoop() { + telemetry.onStart({ callId: "failed", operationId: "ai.streamText" }); + telemetry.onLanguageModelCallStart({ callId: "failed" }); + return {}; + } + } + wrapCloudflareThink({ Think }); + await new Think()._runInferenceLoop(); + const error = new Error("interrupted"); + telemetry[end]({ callId: "failed", error }); + telemetry.onEnd({ callId: "failed", operationId: "ai.streamText" }); + const spans = (await backgroundLogger.drain()) as any[]; + expect(spans).toHaveLength(2); + for (const span of spans) { + expect(span.error).toContain("interrupted"); + expect(span.metrics.end).toEqual(expect.any(Number)); + } + }, + ); + + it("respects AI SDK 7 input and output recording controls", async () => { + const telemetry = braintrustAISDKTelemetry(); + class Think { + messages = [{ role: "user", content: "private fallback" }]; + + async _runInferenceLoop() { + telemetry.onStart({ + callId: "private", + operationId: "ai.streamText", + messages: this.messages, + recordInputs: false, + recordOutputs: false, + }); + return {}; + } + } + wrapCloudflareThink({ Think }); + await new Think()._runInferenceLoop(); + telemetry.onEnd({ + callId: "private", + operationId: "ai.streamText", + text: "private output", + }); + const spans = (await backgroundLogger.drain()) as any[]; + expect(spans).toHaveLength(1); + expect(spans[0].input).toBeUndefined(); + expect(spans[0].output).toBeUndefined(); + }); + + it.each(["disabled", "throws"] as const)( + "does not wait for telemetry when the v7 invocation %s", + async (mode) => { + const error = new Error("invalid stream"); + class Think { + async _runInferenceLoop() { + try { + return aiSDKChannels.streamTextV7.invoke( + () => { + if (mode === "throws") throw error; + return {}; + }, + undefined, + [{ telemetry: { isEnabled: mode !== "disabled" } }], + {}, + ); + } catch (caught) { + expect(caught).toBe(error); + // A Think subclass may recover from a synchronous stream error. + return {}; + } + } + } + wrapCloudflareThink({ Think }); + await new Think()._runInferenceLoop(); + const spans = (await backgroundLogger.drain()) as any[]; + expect(spans).toHaveLength(1); + expect(spans[0].metrics.end).toEqual(expect.any(Number)); + }, + ); + + it("ends a v7 task when prompt validation fails before telemetry starts", async () => { + const telemetry = braintrustAISDKTelemetry(); + let fail: () => void; + class Think { + async _runInferenceLoop() { + return aiSDKChannels.streamTextV7.invoke( + () => { + const span = currentSpan(); + fail = () => + withCurrent(span, () => + telemetry.onError({ + callId: "invalid", + error: new Error("invalid prompt"), + }), + ); + return {}; + }, + undefined, + [{}], + {}, + ); + } + } + wrapCloudflareThink({ Think }); + await new Think()._runInferenceLoop(); + expect(cloudflareThinkSpanCountForTesting()).toBe(1); + fail!(); + const spans = (await backgroundLogger.drain()) as any[]; + expect(spans).toHaveLength(1); + expect(spans[0].error).toContain("invalid prompt"); + expect(spans[0].metrics.end).toEqual(expect.any(Number)); + }); + + it.each([true, false])( + "traces v7 dispatchers once with standalone AI SDK tracing enabled=%s", + async (aisdk) => { + registry.disable(); + registry.configure({ integrations: { aisdk } }); + registry.enable(); + try { + let dispatcher: any; + class Think { + async _runInferenceLoop() { + return aiSDKChannels.streamTextV7.invoke( + () => { + dispatcher = aiSDKChannels.v7CreateTelemetryDispatcher.invoke( + () => ({}), + undefined, + [{}], + {}, + ); + dispatcher.onStart({ + callId: "dispatcher", + operationId: "ai.streamText", + messages: [{ role: "user", content: "Hello" }], + }); + return {}; + }, + undefined, + [{}], + {}, + ); + } + } + wrapCloudflareThink({ Think }); + await new Think()._runInferenceLoop(); + dispatcher.onLanguageModelCallStart({ callId: "dispatcher" }); + dispatcher.onLanguageModelCallEnd({ + callId: "dispatcher", + text: "Hello", + }); + dispatcher.onEnd({ + callId: "dispatcher", + operationId: "ai.streamText", + text: "Hello", + }); + const spans = (await backgroundLogger.drain()) as any[]; + expect(spans).toHaveLength(2); + expect(spans.map((span) => span.span_attributes.name).sort()).toEqual([ + "Think.runTurn", + "doStream", + ]); + } finally { + registry.disable(); + registry.configure({}); + registry.enable(); + } + }, + ); }); function makeStreamingModel(text: string): any { diff --git a/js/src/instrumentation/plugins/cloudflare-think-plugin.ts b/js/src/instrumentation/plugins/cloudflare-think-plugin.ts index 0168af8a0..04c27d84e 100644 --- a/js/src/instrumentation/plugins/cloudflare-think-plugin.ts +++ b/js/src/instrumentation/plugins/cloudflare-think-plugin.ts @@ -19,11 +19,13 @@ import type { ChannelMessage } from "../core/tracing-types"; // tool, output, and usage data that the outer Think call does not expose. import type { AISDKResult } from "../../vendor-sdk-types/ai-sdk"; import type { CloudflareThinkMessage } from "../../vendor-sdk-types/cloudflare-think"; +import { braintrustAISDKTelemetry } from "../../wrappers/ai-sdk/telemetry"; import { aiSDKChannels } from "./ai-sdk-interceptors"; import { DEFAULT_DENY_OUTPUT_PATHS, finalizeAISDKChildTracing, patchAISDKStreamingResult, + patchAISDKV7TelemetryDispatcher, prepareAISDKAgentCallInput, } from "./ai-sdk-plugin"; import { cloudflareThinkChannels } from "./cloudflare-think-interceptors"; @@ -35,6 +37,7 @@ import { type ThinkRunState = { aiEvent?: Record; aiResultPatched: boolean; + telemetryClaimed: boolean; fallbackInput?: unknown; finalized: boolean; inputLogged: boolean; @@ -52,9 +55,38 @@ export class CloudflareThinkPlugin extends BasePlugin { private readonly statesBySpanId = new Map(); protected onEnable(): void { + const telemetry = braintrustAISDKTelemetry(); this.subscribeToThinkRuns(); this.subscribeToAISDKStreamTextSync(); this.subscribeToAISDKStreamTextAsync(); + this.unsubscribers.push( + aiSDKChannels.v7CreateTelemetryDispatcher.intercept( + (target, receiver, args) => { + const dispatcher = Reflect.apply(target, receiver, args); + if (this.currentState() && args[0]?.telemetry?.isEnabled !== false) { + // Think must also work when the standalone AI SDK integration is + // disabled. Dispatcher patching is shared and idempotent. + runInstrumentation(() => + patchAISDKV7TelemetryDispatcher( + dispatcher, + telemetry, + args[0]?.telemetry, + ), + ); + } + return dispatcher; + }, + ), + aiSDKChannels.streamTextV7.intercept((target, receiver, args) => { + const state = this.currentState(); + const result = Reflect.apply(target, receiver, args); + const telemetry = args[0]?.telemetry ?? args[0]?.experimental_telemetry; + if (state && telemetry?.isEnabled !== false) { + state.aiResultPatched = true; + } + return result; + }), + ); } protected onDisable(): void { @@ -94,6 +126,7 @@ export class CloudflareThinkPlugin extends BasePlugin { ); const runState: ThinkRunState = { aiResultPatched: false, + telemetryClaimed: false, fallbackInput: extractFallbackInput(event.self?.messages), finalized: false, inputLogged: false, @@ -114,7 +147,39 @@ export class CloudflareThinkPlugin extends BasePlugin { if (span.spanId) { this.statesBySpanId.set(span.spanId, runState); } - registerCloudflareThinkSpan(span); + registerCloudflareThinkSpan({ + span, + startTelemetry: (input, metadata) => { + // Only the outer inference stream owns this task. A stream started + // inside a tool must retain its own AI SDK operation span. + if (runState.finalized || runState.telemetryClaimed) { + return false; + } + runState.telemetryClaimed = true; + runState.aiResultPatched = true; + runState.inputLogged = true; + span.log({ + ...(input !== undefined + ? { input: extractThinkTaskInput(input) } + : {}), + metadata: { + ...metadata, + braintrust: { + integration_name: "cloudflare-think", + sdk_language: "typescript", + }, + }, + }); + return true; + }, + finishTelemetry: (output, metrics, error) => { + if (runState.finalized) { + return; + } + span.log({ metrics }); + this.finishState(runState, error, output); + }, + }); return runState; }; diff --git a/js/src/vendor-sdk-types/ai-sdk-common.ts b/js/src/vendor-sdk-types/ai-sdk-common.ts index d6483eef5..7945b173c 100644 --- a/js/src/vendor-sdk-types/ai-sdk-common.ts +++ b/js/src/vendor-sdk-types/ai-sdk-common.ts @@ -215,6 +215,8 @@ export interface AISDKRerankParams { } export interface AISDKCallParams { + telemetry?: { isEnabled?: boolean }; + experimental_telemetry?: { isEnabled?: boolean }; model?: AISDKModel; instructions?: unknown; prompt?: string | AISDKMessage[] | Record; diff --git a/js/src/vendor-sdk-types/cloudflare-think.ts b/js/src/vendor-sdk-types/cloudflare-think.ts index 7a5130c05..57aac8b49 100644 --- a/js/src/vendor-sdk-types/cloudflare-think.ts +++ b/js/src/vendor-sdk-types/cloudflare-think.ts @@ -19,6 +19,7 @@ export type CloudflareThinkInstance = { messages?: CloudflareThinkMessage[]; _runInferenceLoop?: ( input: CloudflareThinkTurnInput, + historyLeafId?: string | null, ) => Promise; }; diff --git a/js/src/wrappers/ai-sdk/telemetry.ts b/js/src/wrappers/ai-sdk/telemetry.ts index 12f60a9f2..d86053058 100644 --- a/js/src/wrappers/ai-sdk/telemetry.ts +++ b/js/src/wrappers/ai-sdk/telemetry.ts @@ -43,6 +43,10 @@ import type { } from "../../vendor-sdk-types/ai-sdk-v7-telemetry"; import { BRAINTRUST_AI_SDK_V7_OPERATION_KEY as AI_SDK_V7_OPERATION_KEY } from "../../vendor-sdk-types/ai-sdk-v7-telemetry"; import { currentWorkflowAgentWrapperSpan } from "./workflow-agent-context"; +import { + currentCloudflareThinkRun, + type CloudflareThinkRun, +} from "../../instrumentation/plugins/cloudflare-think-context"; import { currentHarnessTurnParent, startHarnessTurnChildSpan, @@ -57,6 +61,7 @@ type OperationState = { operationName: string; operationKey: string; ownsSpan: boolean; + thinkRun?: CloudflareThinkRun; span: Span; startTime: number; providerTools: Map; @@ -449,7 +454,7 @@ export function braintrustAISDKTelemetry(): any { if (!state) { return; } - if (!state.ownsSpan) { + if (!state.ownsSpan && !state.thinkRun) { deleteOperation(state.operationKey); return; } @@ -472,9 +477,10 @@ export function braintrustAISDKTelemetry(): any { } const result = finishResult(event, state.operationName); - const metrics: Record = state.hadModelChild - ? {} - : extractTokenMetrics(result); + const metrics: Record = + state.hadModelChild && !state.thinkRun + ? {} + : extractTokenMetrics(result); const timeToFirstToken = state.operationName === "WorkflowAgent.stream" ? undefined @@ -483,6 +489,17 @@ export function braintrustAISDKTelemetry(): any { metrics.time_to_first_token = timeToFirstToken; } + if (state.thinkRun) { + state.thinkRun.finishTelemetry( + state.recordOutputs !== false && shouldRecordOutputs(event) + ? result + : undefined, + metrics, + ); + deleteOperation(state.operationKey); + return; + } + state.span.log({ ...(shouldRecordOutputs(event) ? { @@ -545,9 +562,25 @@ export function braintrustAISDKTelemetry(): any { runSafely("onStart", () => { const operationName = operationNameFromId(event.operationId); const workflowAgent = operationName === "WorkflowAgent.stream"; + let thinkRun = + operationName === "streamText" + ? currentCloudflareThinkRun() + : undefined; + if ( + thinkRun && + !thinkRun.startTelemetry( + shouldRecordInputs(event) + ? processAISDKCallInput(operationInput(event, operationName)) + .input + : undefined, + metadataFromEvent(event), + ) + ) { + thinkRun = undefined; + } const wrapperSpan = workflowAgent ? currentWorkflowAgentWrapperSpan() - : undefined; + : thinkRun?.span; const ownsSpan = !wrapperSpan; const harnessTurnParent = currentHarnessTurnParent(); const span = ownsSpan @@ -582,6 +615,7 @@ export function braintrustAISDKTelemetry(): any { operationName, operationKey, ownsSpan, + thinkRun, span, startTime: getCurrentUnixTimestamp(), providerTools: new Map(), @@ -1031,16 +1065,18 @@ export function braintrustAISDKTelemetry(): any { runSafely("onAbort", () => { const operationKey = operationKeyFromEvent(event, "finish"); const state = operationKey ? operations.get(operationKey) : undefined; + const error = abortReasonFromEvent(event); if (!operationKey || !state) { + currentCloudflareThinkRun()?.finishTelemetry(undefined, {}, error); return; } - const error = abortReasonFromEvent(event); closeOpenChildSpans(operationKey, error); if (state.ownsSpan) { logError(state.span, error); state.span.end(); } + state.thinkRun?.finishTelemetry(undefined, {}, error); deleteOperation(operationKey); }); }, @@ -1052,16 +1088,19 @@ export function braintrustAISDKTelemetry(): any { : {}; const operationKey = operationKeyFromEvent(errorEvent, "finish"); const state = operationKey ? operations.get(operationKey) : undefined; + const error = errorEvent.error ?? event; if (!operationKey || !state) { + // Prompt validation can fail before streamText emits onStart. + currentCloudflareThinkRun()?.finishTelemetry(undefined, {}, error); return; } - const error = errorEvent.error ?? event; closeOpenChildSpans(operationKey, error); if (state.ownsSpan) { logError(state.span, error); state.span.end(); } + state.thinkRun?.finishTelemetry(undefined, {}, error); deleteOperation(operationKey); }); }, diff --git a/js/src/wrappers/cloudflare-think.test.ts b/js/src/wrappers/cloudflare-think.test.ts index 05b54e46e..8bbfca976 100644 --- a/js/src/wrappers/cloudflare-think.test.ts +++ b/js/src/wrappers/cloudflare-think.test.ts @@ -72,6 +72,39 @@ describe("wrapCloudflareThink", () => { expect(invoke).toHaveBeenCalledTimes(1); }); + it("preserves the history leaf and argument count used by current Think", async () => { + class Think { + _runInferenceLoop(...args: [unknown, string?]) { + return Promise.resolve({ receiver: this, args }); + } + } + const sdk = wrapCloudflareThink({ Think }); + const instance = new sdk.Think(); + const input = { body: "continue this branch" }; + for (const args of [[input], [input, "history-leaf"]] as [ + unknown, + string?, + ][]) { + await expect(instance._runInferenceLoop(...args)).resolves.toEqual({ + receiver: instance, + args, + }); + } + }); + + it("preserves promise identity and rejection", async () => { + const error = new Error("inference failed"); + const result = Promise.reject(error); + class Think { + _runInferenceLoop() { + return result; + } + } + wrapCloudflareThink({ Think }); + expect(new Think()._runInferenceLoop()).toBe(result); + await expect(result).rejects.toBe(error); + }); + it("preserves the original method descriptor", () => { class Think {} const original = vi.fn(async () => "ok"); diff --git a/js/src/wrappers/cloudflare-think.ts b/js/src/wrappers/cloudflare-think.ts index 39f9516d7..bda6dd5f7 100644 --- a/js/src/wrappers/cloudflare-think.ts +++ b/js/src/wrappers/cloudflare-think.ts @@ -3,7 +3,6 @@ import type { CloudflareThinkConstructor, CloudflareThinkInstance, CloudflareThinkModule, - CloudflareThinkTurnInput, } from "../vendor-sdk-types/cloudflare-think"; const WRAPPED_THINK = Symbol.for("braintrust.cloudflare-think.wrapped"); @@ -55,9 +54,8 @@ function patchThinkClass(Think: CloudflareThinkConstructor): void { ...descriptor, value: function wrappedCloudflareThinkRunInferenceLoop( this: CloudflareThinkInstance, - input: CloudflareThinkTurnInput, + ...args: Parameters ) { - const args = [input] as [CloudflareThinkTurnInput]; return cloudflareThinkChannels.runInferenceLoop.invoke( original, this, From 1b09310f6f3a3e693d04fd337761616a20c349b1 Mon Sep 17 00:00:00 2001 From: lforst <8118419+lforst@users.noreply.github.com> Date: Tue, 20 Oct 2026 13:40:50 +0000 Subject: [PATCH 2/4] Update PR #2640 --- .changeset/cloudflare-think-version-support.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cloudflare-think-version-support.md diff --git a/.changeset/cloudflare-think-version-support.md b/.changeset/cloudflare-think-version-support.md new file mode 100644 index 000000000..f64d4ff98 --- /dev/null +++ b/.changeset/cloudflare-think-version-support.md @@ -0,0 +1,5 @@ +--- +"braintrust": minor +--- + +feat(cloudflare-think): Support versions 0.13 through 0.20 From 7ae5c7263bbc5b04f509315e26079410a539e83e Mon Sep 17 00:00:00 2001 From: lforst <8118419+lforst@users.noreply.github.com> Date: Tue, 20 Oct 2026 16:54:49 +0000 Subject: [PATCH 3/4] Update PR #2640 --- ...dflare-think-v0-14-ai6-auto.span-tree.json | 922 ------------------ ...udflare-think-v0-14-ai6-auto.span-tree.txt | 902 ----------------- ...lare-think-v0-14-ai6-manual.span-tree.json | 921 ----------------- ...flare-think-v0-14-ai6-manual.span-tree.txt | 901 ----------------- ...think-v0-14-latest-ai6-auto.span-tree.json | 922 ------------------ ...-think-v0-14-latest-ai6-auto.span-tree.txt | 902 ----------------- ...ink-v0-14-latest-ai6-manual.span-tree.json | 921 ----------------- ...hink-v0-14-latest-ai6-manual.span-tree.txt | 901 ----------------- ...dflare-think-v0-15-ai6-auto.span-tree.json | 922 ------------------ ...udflare-think-v0-15-ai6-auto.span-tree.txt | 902 ----------------- ...lare-think-v0-15-ai6-manual.span-tree.json | 921 ----------------- ...flare-think-v0-15-ai6-manual.span-tree.txt | 901 ----------------- ...dflare-think-v0-15-ai7-auto.span-tree.json | 736 -------------- ...udflare-think-v0-15-ai7-auto.span-tree.txt | 716 -------------- ...lare-think-v0-15-ai7-manual.span-tree.json | 919 ----------------- ...flare-think-v0-15-ai7-manual.span-tree.txt | 899 ----------------- ...think-v0-15-latest-ai6-auto.span-tree.json | 922 ------------------ ...-think-v0-15-latest-ai6-auto.span-tree.txt | 902 ----------------- ...ink-v0-15-latest-ai6-manual.span-tree.json | 921 ----------------- ...hink-v0-15-latest-ai6-manual.span-tree.txt | 901 ----------------- ...think-v0-15-latest-ai7-auto.span-tree.json | 736 -------------- ...-think-v0-15-latest-ai7-auto.span-tree.txt | 716 -------------- ...ink-v0-15-latest-ai7-manual.span-tree.json | 919 ----------------- ...hink-v0-15-latest-ai7-manual.span-tree.txt | 899 ----------------- ...dflare-think-v0-16-ai6-auto.span-tree.json | 922 ------------------ ...udflare-think-v0-16-ai6-auto.span-tree.txt | 902 ----------------- ...lare-think-v0-16-ai6-manual.span-tree.json | 921 ----------------- ...flare-think-v0-16-ai6-manual.span-tree.txt | 901 ----------------- ...dflare-think-v0-16-ai7-auto.span-tree.json | 736 -------------- ...udflare-think-v0-16-ai7-auto.span-tree.txt | 716 -------------- ...lare-think-v0-16-ai7-manual.span-tree.json | 919 ----------------- ...flare-think-v0-16-ai7-manual.span-tree.txt | 899 ----------------- ...think-v0-16-latest-ai6-auto.span-tree.json | 922 ------------------ ...-think-v0-16-latest-ai6-auto.span-tree.txt | 902 ----------------- ...ink-v0-16-latest-ai6-manual.span-tree.json | 921 ----------------- ...hink-v0-16-latest-ai6-manual.span-tree.txt | 901 ----------------- ...think-v0-16-latest-ai7-auto.span-tree.json | 736 -------------- ...-think-v0-16-latest-ai7-auto.span-tree.txt | 716 -------------- ...ink-v0-16-latest-ai7-manual.span-tree.json | 919 ----------------- ...hink-v0-16-latest-ai7-manual.span-tree.txt | 899 ----------------- ...dflare-think-v0-17-ai6-auto.span-tree.json | 922 ------------------ ...udflare-think-v0-17-ai6-auto.span-tree.txt | 902 ----------------- ...lare-think-v0-17-ai6-manual.span-tree.json | 921 ----------------- ...flare-think-v0-17-ai6-manual.span-tree.txt | 901 ----------------- ...dflare-think-v0-17-ai7-auto.span-tree.json | 736 -------------- ...udflare-think-v0-17-ai7-auto.span-tree.txt | 716 -------------- ...lare-think-v0-17-ai7-manual.span-tree.json | 919 ----------------- ...flare-think-v0-17-ai7-manual.span-tree.txt | 899 ----------------- ...think-v0-17-latest-ai6-auto.span-tree.json | 922 ------------------ ...-think-v0-17-latest-ai6-auto.span-tree.txt | 902 ----------------- ...ink-v0-17-latest-ai6-manual.span-tree.json | 921 ----------------- ...hink-v0-17-latest-ai6-manual.span-tree.txt | 901 ----------------- ...think-v0-17-latest-ai7-auto.span-tree.json | 736 -------------- ...-think-v0-17-latest-ai7-auto.span-tree.txt | 716 -------------- ...ink-v0-17-latest-ai7-manual.span-tree.json | 919 ----------------- ...hink-v0-17-latest-ai7-manual.span-tree.txt | 899 ----------------- ...dflare-think-v0-18-ai6-auto.span-tree.json | 922 ------------------ ...udflare-think-v0-18-ai6-auto.span-tree.txt | 902 ----------------- ...lare-think-v0-18-ai6-manual.span-tree.json | 921 ----------------- ...flare-think-v0-18-ai6-manual.span-tree.txt | 901 ----------------- ...dflare-think-v0-18-ai7-auto.span-tree.json | 736 -------------- ...udflare-think-v0-18-ai7-auto.span-tree.txt | 716 -------------- ...lare-think-v0-18-ai7-manual.span-tree.json | 919 ----------------- ...flare-think-v0-18-ai7-manual.span-tree.txt | 899 ----------------- ...think-v0-18-latest-ai6-auto.span-tree.json | 922 ------------------ ...-think-v0-18-latest-ai6-auto.span-tree.txt | 902 ----------------- ...ink-v0-18-latest-ai6-manual.span-tree.json | 921 ----------------- ...hink-v0-18-latest-ai6-manual.span-tree.txt | 901 ----------------- ...think-v0-18-latest-ai7-auto.span-tree.json | 736 -------------- ...-think-v0-18-latest-ai7-auto.span-tree.txt | 716 -------------- ...ink-v0-18-latest-ai7-manual.span-tree.json | 919 ----------------- ...hink-v0-18-latest-ai7-manual.span-tree.txt | 899 ----------------- ...dflare-think-v0-19-ai6-auto.span-tree.json | 922 ------------------ ...udflare-think-v0-19-ai6-auto.span-tree.txt | 902 ----------------- ...lare-think-v0-19-ai6-manual.span-tree.json | 921 ----------------- ...flare-think-v0-19-ai6-manual.span-tree.txt | 901 ----------------- ...dflare-think-v0-19-ai7-auto.span-tree.json | 736 -------------- ...udflare-think-v0-19-ai7-auto.span-tree.txt | 716 -------------- ...lare-think-v0-19-ai7-manual.span-tree.json | 919 ----------------- ...flare-think-v0-19-ai7-manual.span-tree.txt | 899 ----------------- ...think-v0-19-latest-ai6-auto.span-tree.json | 922 ------------------ ...-think-v0-19-latest-ai6-auto.span-tree.txt | 902 ----------------- ...ink-v0-19-latest-ai6-manual.span-tree.json | 921 ----------------- ...hink-v0-19-latest-ai6-manual.span-tree.txt | 901 ----------------- ...think-v0-19-latest-ai7-auto.span-tree.json | 736 -------------- ...-think-v0-19-latest-ai7-auto.span-tree.txt | 716 -------------- ...ink-v0-19-latest-ai7-manual.span-tree.json | 919 ----------------- ...hink-v0-19-latest-ai7-manual.span-tree.txt | 899 ----------------- .../assertions.ts | 13 +- .../scenario.test.ts | 5 +- 90 files changed, 12 insertions(+), 76458 deletions(-) delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.txt delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.txt diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.json deleted file mode 100644 index cd8111afb..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 24, - "total": 280 - }, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.14.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 448, - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 448, - "time_to_first_token": 0, - "tokens": 2619 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.txt deleted file mode 100644 index 5f3e28dea..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.14.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 448, - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 448, - "time_to_first_token": 0, - "tokens": 2619 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 24, - │ "total": 280 - │ }, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.json deleted file mode 100644 index dda00f7fd..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 384, - "text": 24, - "total": 408 - }, - "raw": { - "completion_tokens": 408, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 384, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1450 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 384, - "completion_tokens": 408, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 384, - "time_to_first_token": 0, - "tokens": 1450 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 512, - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 512, - "time_to_first_token": 0, - "tokens": 2683 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.txt deleted file mode 100644 index 51b69e3c8..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 512, - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 512, - "time_to_first_token": 0, - "tokens": 2683 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 384, - │ "text": 24, - │ "total": 408 - │ }, - │ "raw": { - │ "completion_tokens": 408, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 384, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1450 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 384, - │ "completion_tokens": 408, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 384, - │ "time_to_first_token": 0, - │ "tokens": 1450 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.json deleted file mode 100644 index 22f05d9d2..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 24, - "total": 280 - }, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 0, - "text": 12, - "total": 12 - }, - "raw": { - "completion_tokens": 12, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 0, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1099 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 0, - "completion_tokens": 12, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 0, - "time_to_first_token": 0, - "tokens": 1099 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.14.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 292, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 2421 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.txt deleted file mode 100644 index e2d808d33..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.14.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 256, - "completion_tokens": 292, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 2421 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 24, - │ "total": 280 - │ }, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 0, - "text": 12, - "total": 12 - }, - "raw": { - "completion_tokens": 12, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 0, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1099 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 0, - "completion_tokens": 12, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 0, - "time_to_first_token": 0, - "tokens": 1099 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.json deleted file mode 100644 index 553204794..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 192, - "text": 24, - "total": 216 - }, - "raw": { - "completion_tokens": 216, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1258 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 216, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1258 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 0, - "text": 12, - "total": 12 - }, - "raw": { - "completion_tokens": 12, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 0, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1099 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 0, - "completion_tokens": 12, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 0, - "time_to_first_token": 0, - "tokens": 1099 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 228, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 2357 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.txt deleted file mode 100644 index bd1f22f13..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-14-latest-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 228, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 2357 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 192, - │ "text": 24, - │ "total": 216 - │ }, - │ "raw": { - │ "completion_tokens": 216, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 192, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1258 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 192, - │ "completion_tokens": 216, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 192, - │ "time_to_first_token": 0, - │ "tokens": 1258 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 0, - "text": 12, - "total": 12 - }, - "raw": { - "completion_tokens": 12, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 0, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1099 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 0, - "completion_tokens": 12, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 0, - "time_to_first_token": 0, - "tokens": 1099 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.json deleted file mode 100644 index bd9094769..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 448, - "text": 24, - "total": 472 - }, - "raw": { - "completion_tokens": 472, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 448, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1514 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 448, - "completion_tokens": 472, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 448, - "time_to_first_token": 0, - "tokens": 1514 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 64, - "text": 18, - "total": 82 - }, - "raw": { - "completion_tokens": 82, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 64, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1169 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 64, - "completion_tokens": 82, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 64, - "time_to_first_token": 0, - "tokens": 1169 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.15.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 512, - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 512, - "time_to_first_token": 0, - "tokens": 2683 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.txt deleted file mode 100644 index e0622a581..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.15.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 512, - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 512, - "time_to_first_token": 0, - "tokens": 2683 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 448, - │ "text": 24, - │ "total": 472 - │ }, - │ "raw": { - │ "completion_tokens": 472, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 448, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1514 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 448, - │ "completion_tokens": 472, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 448, - │ "time_to_first_token": 0, - │ "tokens": 1514 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 64, - "text": 18, - "total": 82 - }, - "raw": { - "completion_tokens": 82, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 64, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1169 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 64, - "completion_tokens": 82, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 64, - "time_to_first_token": 0, - "tokens": 1169 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.json deleted file mode 100644 index 15bf7a99e..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 24, - "total": 280 - }, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 384, - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 384, - "time_to_first_token": 0, - "tokens": 2555 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.txt deleted file mode 100644 index 0f9f56bc8..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 384, - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 384, - "time_to_first_token": 0, - "tokens": 2555 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 24, - │ "total": 280 - │ }, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.json deleted file mode 100644 index 9f9222615..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.json +++ /dev/null @@ -1,736 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "finishReason": "tool-calls", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1042 - }, - "inputTokens": 1042, - "outputTokenDetails": { - "reasoningTokens": 256, - "textTokens": 24 - }, - "outputTokens": 280, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - }, - "totalTokens": 1322 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "toolCallId": "", - "toolName": "lookup_weather" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 192, - "textTokens": 18 - }, - "outputTokens": 210, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - }, - "totalTokens": 1297 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.15.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2619 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.txt deleted file mode 100644 index 04d4a7d48..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-auto.span-tree.txt +++ /dev/null @@ -1,716 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.15.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2619 - } - ├── doStream [llm] - │ input: { - │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "messages": [ - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "model": { - │ "modelId": "gpt-5-nano", - │ "provider": "openai.chat" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "content": [ - │ { - │ "input": { - │ "city": "Vienna" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "finishReason": "tool-calls", - │ "providerMetadata": { - │ "openai": { - │ "acceptedPredictionTokens": 0, - │ "rejectedPredictionTokens": 0 - │ } - │ }, - │ "response": { - │ "id": "" - │ }, - │ "usage": { - │ "inputTokenDetails": { - │ "cacheReadTokens": 0, - │ "noCacheTokens": 1042 - │ }, - │ "inputTokens": 1042, - │ "outputTokenDetails": { - │ "reasoningTokens": 256, - │ "textTokens": 24 - │ }, - │ "outputTokens": 280, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ }, - │ "totalTokens": 1322 - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "functionId": "TestThink", - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather" - │ } - └── doStream [llm] - input: { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 192, - "textTokens": 18 - }, - "outputTokens": 210, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - }, - "totalTokens": 1297 - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.json deleted file mode 100644 index d696ec9a5..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.json +++ /dev/null @@ -1,919 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 320, - "text": 24, - "total": 344 - }, - "raw": { - "completion_tokens": 344, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1386 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 320, - "completion_tokens": 344, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 1386 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 0, - "text": 12, - "total": 12 - }, - "raw": { - "completion_tokens": 12, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 0, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1099 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 0, - "completion_tokens": 12, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 0, - "time_to_first_token": 0, - "tokens": 1099 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_tokens": 356, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2485 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.txt deleted file mode 100644 index c2864efa8..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-ai7-manual.span-tree.txt +++ /dev/null @@ -1,899 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_tokens": 356, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2485 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 320, - │ "text": 24, - │ "total": 344 - │ }, - │ "raw": { - │ "completion_tokens": 344, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 320, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1386 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 320, - │ "completion_tokens": 344, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 320, - │ "time_to_first_token": 0, - │ "tokens": 1386 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 0, - "text": 12, - "total": 12 - }, - "raw": { - "completion_tokens": 12, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 0, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1099 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 0, - "completion_tokens": 12, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 0, - "time_to_first_token": 0, - "tokens": 1099 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.json deleted file mode 100644 index e1a1f66c0..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 384, - "text": 24, - "total": 408 - }, - "raw": { - "completion_tokens": 408, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 384, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1450 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 384, - "completion_tokens": 408, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 384, - "time_to_first_token": 0, - "tokens": 1450 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.15.1", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 512, - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 512, - "time_to_first_token": 0, - "tokens": 2683 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.txt deleted file mode 100644 index 0cb046e1c..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.15.1", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 512, - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 512, - "time_to_first_token": 0, - "tokens": 2683 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 384, - │ "text": 24, - │ "total": 408 - │ }, - │ "raw": { - │ "completion_tokens": 408, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 384, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1450 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 384, - │ "completion_tokens": 408, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 384, - │ "time_to_first_token": 0, - │ "tokens": 1450 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.json deleted file mode 100644 index d113870e7..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 192, - "text": 24, - "total": 216 - }, - "raw": { - "completion_tokens": 216, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1258 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 216, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1258 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 384, - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 384, - "time_to_first_token": 0, - "tokens": 2555 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.txt deleted file mode 100644 index 93e394db2..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 384, - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 384, - "time_to_first_token": 0, - "tokens": 2555 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 192, - │ "text": 24, - │ "total": 216 - │ }, - │ "raw": { - │ "completion_tokens": 216, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 192, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1258 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 192, - │ "completion_tokens": 216, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 192, - │ "time_to_first_token": 0, - │ "tokens": 1258 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.json deleted file mode 100644 index 7e9196010..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.json +++ /dev/null @@ -1,736 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "finishReason": "tool-calls", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1042 - }, - "inputTokens": 1042, - "outputTokenDetails": { - "reasoningTokens": 256, - "textTokens": 24 - }, - "outputTokens": 280, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - }, - "totalTokens": 1322 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "toolCallId": "", - "toolName": "lookup_weather" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.15.1", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2555 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.txt deleted file mode 100644 index 66b2d2572..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-auto.span-tree.txt +++ /dev/null @@ -1,716 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.15.1", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2555 - } - ├── doStream [llm] - │ input: { - │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "messages": [ - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "model": { - │ "modelId": "gpt-5-nano", - │ "provider": "openai.chat" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "content": [ - │ { - │ "input": { - │ "city": "Vienna" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "finishReason": "tool-calls", - │ "providerMetadata": { - │ "openai": { - │ "acceptedPredictionTokens": 0, - │ "rejectedPredictionTokens": 0 - │ } - │ }, - │ "response": { - │ "id": "" - │ }, - │ "usage": { - │ "inputTokenDetails": { - │ "cacheReadTokens": 0, - │ "noCacheTokens": 1042 - │ }, - │ "inputTokens": 1042, - │ "outputTokenDetails": { - │ "reasoningTokens": 256, - │ "textTokens": 24 - │ }, - │ "outputTokens": 280, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ }, - │ "totalTokens": 1322 - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "functionId": "TestThink", - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather" - │ } - └── doStream [llm] - input: { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.json deleted file mode 100644 index c6d838c7c..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.json +++ /dev/null @@ -1,919 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 512, - "text": 24, - "total": 536 - }, - "raw": { - "completion_tokens": 536, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 512, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1578 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 512, - "completion_tokens": 536, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 512, - "time_to_first_token": 0, - "tokens": 1578 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_tokens": 746, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2875 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.txt deleted file mode 100644 index f4ee26a54..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-15-latest-ai7-manual.span-tree.txt +++ /dev/null @@ -1,899 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_tokens": 746, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2875 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 512, - │ "text": 24, - │ "total": 536 - │ }, - │ "raw": { - │ "completion_tokens": 536, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 512, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1578 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 512, - │ "completion_tokens": 536, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 512, - │ "time_to_first_token": 0, - │ "tokens": 1578 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.json deleted file mode 100644 index 002ec074e..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 24, - "total": 280 - }, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 18, - "total": 274 - }, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1361 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.16.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 512, - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 512, - "time_to_first_token": 0, - "tokens": 2683 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.txt deleted file mode 100644 index 38f12dc23..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.16.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 512, - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 512, - "time_to_first_token": 0, - "tokens": 2683 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 24, - │ "total": 280 - │ }, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 18, - "total": 274 - }, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 256, - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1361 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.json deleted file mode 100644 index 19098c709..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 576, - "text": 24, - "total": 600 - }, - "raw": { - "completion_tokens": 600, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 576, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1642 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 576, - "completion_tokens": 600, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 576, - "time_to_first_token": 0, - "tokens": 1642 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 768, - "completion_tokens": 810, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 768, - "time_to_first_token": 0, - "tokens": 2939 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.txt deleted file mode 100644 index 89fd3bfa2..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 768, - "completion_tokens": 810, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 768, - "time_to_first_token": 0, - "tokens": 2939 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 576, - │ "text": 24, - │ "total": 600 - │ }, - │ "raw": { - │ "completion_tokens": 600, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 576, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1642 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 576, - │ "completion_tokens": 600, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 576, - │ "time_to_first_token": 0, - │ "tokens": 1642 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.json deleted file mode 100644 index 2013e1597..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.json +++ /dev/null @@ -1,736 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "finishReason": "tool-calls", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1042 - }, - "inputTokens": 1042, - "outputTokenDetails": { - "reasoningTokens": 256, - "textTokens": 24 - }, - "outputTokens": 280, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - }, - "totalTokens": 1322 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "toolCallId": "", - "toolName": "lookup_weather" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 320, - "textTokens": 18 - }, - "outputTokens": 338, - "raw": { - "completion_tokens": 338, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1425 - }, - "totalTokens": 1425 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 338, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1425 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.16.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 618, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2747 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.txt deleted file mode 100644 index 8282bcccb..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-auto.span-tree.txt +++ /dev/null @@ -1,716 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.16.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 618, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2747 - } - ├── doStream [llm] - │ input: { - │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "messages": [ - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "model": { - │ "modelId": "gpt-5-nano", - │ "provider": "openai.chat" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "content": [ - │ { - │ "input": { - │ "city": "Vienna" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "finishReason": "tool-calls", - │ "providerMetadata": { - │ "openai": { - │ "acceptedPredictionTokens": 0, - │ "rejectedPredictionTokens": 0 - │ } - │ }, - │ "response": { - │ "id": "" - │ }, - │ "usage": { - │ "inputTokenDetails": { - │ "cacheReadTokens": 0, - │ "noCacheTokens": 1042 - │ }, - │ "inputTokens": 1042, - │ "outputTokenDetails": { - │ "reasoningTokens": 256, - │ "textTokens": 24 - │ }, - │ "outputTokens": 280, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ }, - │ "totalTokens": 1322 - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "functionId": "TestThink", - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather" - │ } - └── doStream [llm] - input: { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 320, - "textTokens": 18 - }, - "outputTokens": 338, - "raw": { - "completion_tokens": 338, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1425 - }, - "totalTokens": 1425 - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 338, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1425 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.json deleted file mode 100644 index 6cf811fa2..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.json +++ /dev/null @@ -1,919 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 192, - "text": 24, - "total": 216 - }, - "raw": { - "completion_tokens": 216, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1258 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 216, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1258 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2555 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.txt deleted file mode 100644 index 1a020a594..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-ai7-manual.span-tree.txt +++ /dev/null @@ -1,899 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2555 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 192, - │ "text": 24, - │ "total": 216 - │ }, - │ "raw": { - │ "completion_tokens": 216, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 192, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1258 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 192, - │ "completion_tokens": 216, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 192, - │ "time_to_first_token": 0, - │ "tokens": 1258 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.json deleted file mode 100644 index 11c0e5ce7..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 24, - "total": 280 - }, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 19, - "total": 275 - }, - "raw": { - "completion_tokens": 275, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1362 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 275, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1362 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.16.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 512, - "completion_tokens": 555, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 512, - "time_to_first_token": 0, - "tokens": 2684 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.txt deleted file mode 100644 index 2161b4a8b..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.16.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 512, - "completion_tokens": 555, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 512, - "time_to_first_token": 0, - "tokens": 2684 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 24, - │ "total": 280 - │ }, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 19, - "total": 275 - }, - "raw": { - "completion_tokens": 275, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1362 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 256, - "completion_tokens": 275, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1362 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.json deleted file mode 100644 index 9768297eb..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 320, - "text": 24, - "total": 344 - }, - "raw": { - "completion_tokens": 344, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1386 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 320, - "completion_tokens": 344, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 1386 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 18, - "total": 274 - }, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1361 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 576, - "completion_tokens": 618, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 576, - "time_to_first_token": 0, - "tokens": 2747 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.txt deleted file mode 100644 index c281ee29c..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 576, - "completion_tokens": 618, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 576, - "time_to_first_token": 0, - "tokens": 2747 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 320, - │ "text": 24, - │ "total": 344 - │ }, - │ "raw": { - │ "completion_tokens": 344, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 320, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1386 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 320, - │ "completion_tokens": 344, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 320, - │ "time_to_first_token": 0, - │ "tokens": 1386 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 18, - "total": 274 - }, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 256, - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1361 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.json deleted file mode 100644 index 45d55b9b7..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.json +++ /dev/null @@ -1,736 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "finishReason": "tool-calls", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1042 - }, - "inputTokens": 1042, - "outputTokenDetails": { - "reasoningTokens": 256, - "textTokens": 24 - }, - "outputTokens": 280, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - }, - "totalTokens": 1322 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "toolCallId": "", - "toolName": "lookup_weather" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.16.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2555 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.txt deleted file mode 100644 index 78b7aaf04..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-auto.span-tree.txt +++ /dev/null @@ -1,716 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.16.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2555 - } - ├── doStream [llm] - │ input: { - │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "messages": [ - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "model": { - │ "modelId": "gpt-5-nano", - │ "provider": "openai.chat" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "content": [ - │ { - │ "input": { - │ "city": "Vienna" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "finishReason": "tool-calls", - │ "providerMetadata": { - │ "openai": { - │ "acceptedPredictionTokens": 0, - │ "rejectedPredictionTokens": 0 - │ } - │ }, - │ "response": { - │ "id": "" - │ }, - │ "usage": { - │ "inputTokenDetails": { - │ "cacheReadTokens": 0, - │ "noCacheTokens": 1042 - │ }, - │ "inputTokens": 1042, - │ "outputTokenDetails": { - │ "reasoningTokens": 256, - │ "textTokens": 24 - │ }, - │ "outputTokens": 280, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ }, - │ "totalTokens": 1322 - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "functionId": "TestThink", - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather" - │ } - └── doStream [llm] - input: { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.json deleted file mode 100644 index 6aa5672b0..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.json +++ /dev/null @@ -1,919 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 320, - "text": 24, - "total": 344 - }, - "raw": { - "completion_tokens": 344, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1386 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 320, - "completion_tokens": 344, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 1386 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2683 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.txt deleted file mode 100644 index 39efb478b..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-16-latest-ai7-manual.span-tree.txt +++ /dev/null @@ -1,899 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2683 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 320, - │ "text": 24, - │ "total": 344 - │ }, - │ "raw": { - │ "completion_tokens": 344, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 320, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1386 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 320, - │ "completion_tokens": 344, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 320, - │ "time_to_first_token": 0, - │ "tokens": 1386 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.json deleted file mode 100644 index 411bafadb..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 192, - "text": 24, - "total": 216 - }, - "raw": { - "completion_tokens": 216, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1258 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 216, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1258 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.17.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 320, - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 2491 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.txt deleted file mode 100644 index e8b6b5f21..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.17.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 320, - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 2491 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 192, - │ "text": 24, - │ "total": 216 - │ }, - │ "raw": { - │ "completion_tokens": 216, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 192, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1258 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 192, - │ "completion_tokens": 216, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 192, - │ "time_to_first_token": 0, - │ "tokens": 1258 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.json deleted file mode 100644 index 99acecd24..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 24, - "total": 280 - }, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 448, - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 448, - "time_to_first_token": 0, - "tokens": 2619 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.txt deleted file mode 100644 index 5425b2d9f..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 448, - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 448, - "time_to_first_token": 0, - "tokens": 2619 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 24, - │ "total": 280 - │ }, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.json deleted file mode 100644 index 73db5c04c..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.json +++ /dev/null @@ -1,736 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "finishReason": "tool-calls", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1042 - }, - "inputTokens": 1042, - "outputTokenDetails": { - "reasoningTokens": 384, - "textTokens": 24 - }, - "outputTokens": 408, - "raw": { - "completion_tokens": 408, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 384, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1450 - }, - "totalTokens": 1450 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 408, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "tokens": 1450 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "toolCallId": "", - "toolName": "lookup_weather" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 256, - "textTokens": 18 - }, - "outputTokens": 274, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - }, - "totalTokens": 1361 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1361 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.17.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 682, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2811 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.txt deleted file mode 100644 index 6c1c8d621..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-auto.span-tree.txt +++ /dev/null @@ -1,716 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.17.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 682, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2811 - } - ├── doStream [llm] - │ input: { - │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "messages": [ - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "model": { - │ "modelId": "gpt-5-nano", - │ "provider": "openai.chat" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "content": [ - │ { - │ "input": { - │ "city": "Vienna" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "finishReason": "tool-calls", - │ "providerMetadata": { - │ "openai": { - │ "acceptedPredictionTokens": 0, - │ "rejectedPredictionTokens": 0 - │ } - │ }, - │ "response": { - │ "id": "" - │ }, - │ "usage": { - │ "inputTokenDetails": { - │ "cacheReadTokens": 0, - │ "noCacheTokens": 1042 - │ }, - │ "inputTokens": 1042, - │ "outputTokenDetails": { - │ "reasoningTokens": 384, - │ "textTokens": 24 - │ }, - │ "outputTokens": 408, - │ "raw": { - │ "completion_tokens": 408, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 384, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1450 - │ }, - │ "totalTokens": 1450 - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "functionId": "TestThink", - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_tokens": 408, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "tokens": 1450 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather" - │ } - └── doStream [llm] - input: { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 256, - "textTokens": 18 - }, - "outputTokens": 274, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - }, - "totalTokens": 1361 - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1361 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.json deleted file mode 100644 index 2cfa395c1..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.json +++ /dev/null @@ -1,919 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 24, - "total": 280 - }, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2619 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.txt deleted file mode 100644 index 62de172a1..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-ai7-manual.span-tree.txt +++ /dev/null @@ -1,899 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2619 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 24, - │ "total": 280 - │ }, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.json deleted file mode 100644 index 684987372..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 24, - "total": 280 - }, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 0, - "text": 12, - "total": 12 - }, - "raw": { - "completion_tokens": 12, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 0, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1099 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 0, - "completion_tokens": 12, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 0, - "time_to_first_token": 0, - "tokens": 1099 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.17.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 292, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 2421 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.txt deleted file mode 100644 index 93226bdfd..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.17.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 256, - "completion_tokens": 292, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 2421 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 24, - │ "total": 280 - │ }, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 0, - "text": 12, - "total": 12 - }, - "raw": { - "completion_tokens": 12, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 0, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1099 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 0, - "completion_tokens": 12, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 0, - "time_to_first_token": 0, - "tokens": 1099 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.json deleted file mode 100644 index 72219008f..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 192, - "text": 24, - "total": 216 - }, - "raw": { - "completion_tokens": 216, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1258 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 216, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1258 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 320, - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 2491 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.txt deleted file mode 100644 index 6b292f056..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 320, - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 2491 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 192, - │ "text": 24, - │ "total": 216 - │ }, - │ "raw": { - │ "completion_tokens": 216, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 192, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1258 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 192, - │ "completion_tokens": 216, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 192, - │ "time_to_first_token": 0, - │ "tokens": 1258 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.json deleted file mode 100644 index 05487f627..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.json +++ /dev/null @@ -1,736 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "finishReason": "tool-calls", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1042 - }, - "inputTokens": 1042, - "outputTokenDetails": { - "reasoningTokens": 320, - "textTokens": 24 - }, - "outputTokens": 344, - "raw": { - "completion_tokens": 344, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1386 - }, - "totalTokens": 1386 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 344, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "tokens": 1386 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "toolCallId": "", - "toolName": "lookup_weather" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.17.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2619 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.txt deleted file mode 100644 index f844a4068..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-auto.span-tree.txt +++ /dev/null @@ -1,716 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.17.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2619 - } - ├── doStream [llm] - │ input: { - │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "messages": [ - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "model": { - │ "modelId": "gpt-5-nano", - │ "provider": "openai.chat" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "content": [ - │ { - │ "input": { - │ "city": "Vienna" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "finishReason": "tool-calls", - │ "providerMetadata": { - │ "openai": { - │ "acceptedPredictionTokens": 0, - │ "rejectedPredictionTokens": 0 - │ } - │ }, - │ "response": { - │ "id": "" - │ }, - │ "usage": { - │ "inputTokenDetails": { - │ "cacheReadTokens": 0, - │ "noCacheTokens": 1042 - │ }, - │ "inputTokens": 1042, - │ "outputTokenDetails": { - │ "reasoningTokens": 320, - │ "textTokens": 24 - │ }, - │ "outputTokens": 344, - │ "raw": { - │ "completion_tokens": 344, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 320, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1386 - │ }, - │ "totalTokens": 1386 - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "functionId": "TestThink", - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_tokens": 344, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "tokens": 1386 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather" - │ } - └── doStream [llm] - input: { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.json deleted file mode 100644 index 2cfa395c1..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.json +++ /dev/null @@ -1,919 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 24, - "total": 280 - }, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2619 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.txt deleted file mode 100644 index 62de172a1..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-17-latest-ai7-manual.span-tree.txt +++ /dev/null @@ -1,899 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_tokens": 490, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2619 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 24, - │ "total": 280 - │ }, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.json deleted file mode 100644 index 75b82834a..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 25, - "total": 281 - }, - "raw": { - "completion_tokens": 281, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1323 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 281, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1323 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 320, - "text": 18, - "total": 338 - }, - "raw": { - "completion_tokens": 338, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1425 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 320, - "completion_tokens": 338, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 1425 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.18.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 576, - "completion_tokens": 619, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 576, - "time_to_first_token": 0, - "tokens": 2748 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.txt deleted file mode 100644 index 230ab3a14..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.18.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 576, - "completion_tokens": 619, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 576, - "time_to_first_token": 0, - "tokens": 2748 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 25, - │ "total": 281 - │ }, - │ "raw": { - │ "completion_tokens": 281, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1323 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 281, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1323 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 320, - "text": 18, - "total": 338 - }, - "raw": { - "completion_tokens": 338, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1425 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 320, - "completion_tokens": 338, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 1425 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.json deleted file mode 100644 index 19417d885..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 384, - "text": 24, - "total": 408 - }, - "raw": { - "completion_tokens": 408, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 384, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1450 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 384, - "completion_tokens": 408, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 384, - "time_to_first_token": 0, - "tokens": 1450 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 18, - "total": 274 - }, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1361 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 640, - "completion_tokens": 682, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 640, - "time_to_first_token": 0, - "tokens": 2811 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.txt deleted file mode 100644 index bb77d8e98..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 640, - "completion_tokens": 682, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 640, - "time_to_first_token": 0, - "tokens": 2811 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 384, - │ "text": 24, - │ "total": 408 - │ }, - │ "raw": { - │ "completion_tokens": 408, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 384, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1450 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 384, - │ "completion_tokens": 408, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 384, - │ "time_to_first_token": 0, - │ "tokens": 1450 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 18, - "total": 274 - }, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 256, - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1361 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.json deleted file mode 100644 index 4b774d5a3..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.json +++ /dev/null @@ -1,736 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "finishReason": "tool-calls", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1042 - }, - "inputTokens": 1042, - "outputTokenDetails": { - "reasoningTokens": 320, - "textTokens": 24 - }, - "outputTokens": 344, - "raw": { - "completion_tokens": 344, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1386 - }, - "totalTokens": 1386 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 344, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "tokens": 1386 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "toolCallId": "", - "toolName": "lookup_weather" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 192, - "textTokens": 18 - }, - "outputTokens": 210, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - }, - "totalTokens": 1297 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.18.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2683 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.txt deleted file mode 100644 index 9a02345fc..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-auto.span-tree.txt +++ /dev/null @@ -1,716 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.18.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2683 - } - ├── doStream [llm] - │ input: { - │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "messages": [ - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "model": { - │ "modelId": "gpt-5-nano", - │ "provider": "openai.chat" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "content": [ - │ { - │ "input": { - │ "city": "Vienna" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "finishReason": "tool-calls", - │ "providerMetadata": { - │ "openai": { - │ "acceptedPredictionTokens": 0, - │ "rejectedPredictionTokens": 0 - │ } - │ }, - │ "response": { - │ "id": "" - │ }, - │ "usage": { - │ "inputTokenDetails": { - │ "cacheReadTokens": 0, - │ "noCacheTokens": 1042 - │ }, - │ "inputTokens": 1042, - │ "outputTokenDetails": { - │ "reasoningTokens": 320, - │ "textTokens": 24 - │ }, - │ "outputTokens": 344, - │ "raw": { - │ "completion_tokens": 344, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 320, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1386 - │ }, - │ "totalTokens": 1386 - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "functionId": "TestThink", - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_tokens": 344, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "tokens": 1386 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather" - │ } - └── doStream [llm] - input: { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 192, - "textTokens": 18 - }, - "outputTokens": 210, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - }, - "totalTokens": 1297 - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.json deleted file mode 100644 index 2c681de25..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.json +++ /dev/null @@ -1,919 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 24, - "total": 280 - }, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 18, - "total": 274 - }, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1361 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2683 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.txt deleted file mode 100644 index 78a998e7f..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-ai7-manual.span-tree.txt +++ /dev/null @@ -1,899 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2683 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 24, - │ "total": 280 - │ }, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 18, - "total": 274 - }, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 256, - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1361 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.json deleted file mode 100644 index 4ce3a2b17..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 320, - "text": 24, - "total": 344 - }, - "raw": { - "completion_tokens": 344, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1386 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 320, - "completion_tokens": 344, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 1386 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 18, - "total": 274 - }, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1361 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.18.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 576, - "completion_tokens": 618, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 576, - "time_to_first_token": 0, - "tokens": 2747 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.txt deleted file mode 100644 index de1f3b666..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.18.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 576, - "completion_tokens": 618, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 576, - "time_to_first_token": 0, - "tokens": 2747 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 320, - │ "text": 24, - │ "total": 344 - │ }, - │ "raw": { - │ "completion_tokens": 344, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 320, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1386 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 320, - │ "completion_tokens": 344, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 320, - │ "time_to_first_token": 0, - │ "tokens": 1386 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 256, - "text": 18, - "total": 274 - }, - "raw": { - "completion_tokens": 274, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1361 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 256, - "completion_tokens": 274, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1361 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.json deleted file mode 100644 index 60368e288..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 448, - "text": 24, - "total": 472 - }, - "raw": { - "completion_tokens": 472, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 448, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1514 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 448, - "completion_tokens": 472, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 448, - "time_to_first_token": 0, - "tokens": 1514 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 640, - "completion_tokens": 682, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 640, - "time_to_first_token": 0, - "tokens": 2811 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.txt deleted file mode 100644 index 8b4dc2750..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 640, - "completion_tokens": 682, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 640, - "time_to_first_token": 0, - "tokens": 2811 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 448, - │ "text": 24, - │ "total": 472 - │ }, - │ "raw": { - │ "completion_tokens": 472, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 448, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1514 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 448, - │ "completion_tokens": 472, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 448, - │ "time_to_first_token": 0, - │ "tokens": 1514 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.json deleted file mode 100644 index 29f3f51a1..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.json +++ /dev/null @@ -1,736 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "finishReason": "tool-calls", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1042 - }, - "inputTokens": 1042, - "outputTokenDetails": { - "reasoningTokens": 192, - "textTokens": 24 - }, - "outputTokens": 216, - "raw": { - "completion_tokens": 216, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1258 - }, - "totalTokens": 1258 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 216, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "tokens": 1258 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "toolCallId": "", - "toolName": "lookup_weather" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.18.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2491 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.txt deleted file mode 100644 index f153d9848..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-auto.span-tree.txt +++ /dev/null @@ -1,716 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.18.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2491 - } - ├── doStream [llm] - │ input: { - │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "messages": [ - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "model": { - │ "modelId": "gpt-5-nano", - │ "provider": "openai.chat" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "content": [ - │ { - │ "input": { - │ "city": "Vienna" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "finishReason": "tool-calls", - │ "providerMetadata": { - │ "openai": { - │ "acceptedPredictionTokens": 0, - │ "rejectedPredictionTokens": 0 - │ } - │ }, - │ "response": { - │ "id": "" - │ }, - │ "usage": { - │ "inputTokenDetails": { - │ "cacheReadTokens": 0, - │ "noCacheTokens": 1042 - │ }, - │ "inputTokens": 1042, - │ "outputTokenDetails": { - │ "reasoningTokens": 192, - │ "textTokens": 24 - │ }, - │ "outputTokens": 216, - │ "raw": { - │ "completion_tokens": 216, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 192, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1258 - │ }, - │ "totalTokens": 1258 - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "functionId": "TestThink", - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_tokens": 216, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "tokens": 1258 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather" - │ } - └── doStream [llm] - input: { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.json deleted file mode 100644 index 6aa5672b0..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.json +++ /dev/null @@ -1,919 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 320, - "text": 24, - "total": 344 - }, - "raw": { - "completion_tokens": 344, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1386 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 320, - "completion_tokens": 344, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 1386 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2683 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.txt deleted file mode 100644 index 39efb478b..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-18-latest-ai7-manual.span-tree.txt +++ /dev/null @@ -1,899 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_tokens": 554, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2683 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 320, - │ "text": 24, - │ "total": 344 - │ }, - │ "raw": { - │ "completion_tokens": 344, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 320, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1386 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 320, - │ "completion_tokens": 344, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 320, - │ "time_to_first_token": 0, - │ "tokens": 1386 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.json deleted file mode 100644 index 3d2ccc456..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 192, - "text": 24, - "total": 216 - }, - "raw": { - "completion_tokens": 216, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1258 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 216, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1258 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.19.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 320, - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 2491 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.txt deleted file mode 100644 index 9ba33fd26..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.19.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 320, - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 2491 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 192, - │ "text": 24, - │ "total": 216 - │ }, - │ "raw": { - │ "completion_tokens": 216, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 192, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1258 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 192, - │ "completion_tokens": 216, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 192, - │ "time_to_first_token": 0, - │ "tokens": 1258 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.json deleted file mode 100644 index 900434445..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 320, - "text": 24, - "total": 344 - }, - "raw": { - "completion_tokens": 344, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1386 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 320, - "completion_tokens": 344, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 1386 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 64, - "text": 18, - "total": 82 - }, - "raw": { - "completion_tokens": 82, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 64, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1169 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 64, - "completion_tokens": 82, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 64, - "time_to_first_token": 0, - "tokens": 1169 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 384, - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 384, - "time_to_first_token": 0, - "tokens": 2555 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.txt deleted file mode 100644 index 2e61e7f18..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 384, - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 384, - "time_to_first_token": 0, - "tokens": 2555 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 320, - │ "text": 24, - │ "total": 344 - │ }, - │ "raw": { - │ "completion_tokens": 344, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 320, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1386 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 320, - │ "completion_tokens": 344, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 320, - │ "time_to_first_token": 0, - │ "tokens": 1386 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 64, - "text": 18, - "total": 82 - }, - "raw": { - "completion_tokens": 82, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 64, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1169 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 64, - "completion_tokens": 82, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 64, - "time_to_first_token": 0, - "tokens": 1169 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.json deleted file mode 100644 index e7e6bfae0..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.json +++ /dev/null @@ -1,736 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "finishReason": "tool-calls", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1042 - }, - "inputTokens": 1042, - "outputTokenDetails": { - "reasoningTokens": 256, - "textTokens": 24 - }, - "outputTokens": 280, - "raw": { - "completion_tokens": 280, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1322 - }, - "totalTokens": 1322 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 280, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "tokens": 1322 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "toolCallId": "", - "toolName": "lookup_weather" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.19.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2555 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.txt deleted file mode 100644 index 6700fe731..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-auto.span-tree.txt +++ /dev/null @@ -1,716 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.19.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2555 - } - ├── doStream [llm] - │ input: { - │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "messages": [ - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "model": { - │ "modelId": "gpt-5-nano", - │ "provider": "openai.chat" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "content": [ - │ { - │ "input": { - │ "city": "Vienna" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "finishReason": "tool-calls", - │ "providerMetadata": { - │ "openai": { - │ "acceptedPredictionTokens": 0, - │ "rejectedPredictionTokens": 0 - │ } - │ }, - │ "response": { - │ "id": "" - │ }, - │ "usage": { - │ "inputTokenDetails": { - │ "cacheReadTokens": 0, - │ "noCacheTokens": 1042 - │ }, - │ "inputTokens": 1042, - │ "outputTokenDetails": { - │ "reasoningTokens": 256, - │ "textTokens": 24 - │ }, - │ "outputTokens": 280, - │ "raw": { - │ "completion_tokens": 280, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1322 - │ }, - │ "totalTokens": 1322 - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "functionId": "TestThink", - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_tokens": 280, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "tokens": 1322 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather" - │ } - └── doStream [llm] - input: { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.json deleted file mode 100644 index 6cf811fa2..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.json +++ /dev/null @@ -1,919 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 192, - "text": 24, - "total": 216 - }, - "raw": { - "completion_tokens": 216, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1258 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 216, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1258 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2555 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.txt deleted file mode 100644 index 1a020a594..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-ai7-manual.span-tree.txt +++ /dev/null @@ -1,899 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2555 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 192, - │ "text": 24, - │ "total": 216 - │ }, - │ "raw": { - │ "completion_tokens": 216, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 192, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1258 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 192, - │ "completion_tokens": 216, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 192, - │ "time_to_first_token": 0, - │ "tokens": 1258 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 192, - "text": 18, - "total": 210 - }, - "raw": { - "completion_tokens": 210, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1297 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 192, - "completion_tokens": 210, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1297 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.json deleted file mode 100644 index 2f5203aa0..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.json +++ /dev/null @@ -1,922 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 320, - "text": 24, - "total": 344 - }, - "raw": { - "completion_tokens": 344, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 320, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1386 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 320, - "completion_tokens": 344, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 320, - "time_to_first_token": 0, - "tokens": 1386 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 64, - "text": 18, - "total": 82 - }, - "raw": { - "completion_tokens": 82, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 64, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1169 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 64, - "completion_tokens": 82, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 64, - "time_to_first_token": 0, - "tokens": 1169 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.19.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 384, - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 384, - "time_to_first_token": 0, - "tokens": 2555 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.txt deleted file mode 100644 index cfcd68142..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-auto.span-tree.txt +++ /dev/null @@ -1,902 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.19.0", - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 384, - "completion_tokens": 426, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 384, - "time_to_first_token": 0, - "tokens": 2555 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 320, - │ "text": 24, - │ "total": 344 - │ }, - │ "raw": { - │ "completion_tokens": 344, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 320, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1386 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 320, - │ "completion_tokens": 344, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 320, - │ "time_to_first_token": 0, - │ "tokens": 1386 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 64, - "text": 18, - "total": 82 - }, - "raw": { - "completion_tokens": 82, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 64, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1169 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 64, - "completion_tokens": 82, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 64, - "time_to_first_token": 0, - "tokens": 1169 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.json deleted file mode 100644 index eafb3fbdb..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.json +++ /dev/null @@ -1,921 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 256, - "text": 25, - "total": 281 - }, - "raw": { - "completion_tokens": 281, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 256, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1323 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 281, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 1323 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 0, - "text": 12, - "total": 12 - }, - "raw": { - "completion_tokens": 12, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 0, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1099 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 0, - "completion_tokens": 12, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 0, - "time_to_first_token": 0, - "tokens": 1099 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_reasoning_tokens": 256, - "completion_tokens": 293, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 2422 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.txt deleted file mode 100644 index 76c6c0192..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai6-manual.span-tree.txt +++ /dev/null @@ -1,901 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_reasoning_tokens": 256, - "completion_tokens": 293, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "reasoning_tokens": 256, - "time_to_first_token": 0, - "tokens": 2422 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 256, - │ "text": 25, - │ "total": 281 - │ }, - │ "raw": { - │ "completion_tokens": 281, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 256, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1323 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 256, - │ "completion_tokens": 281, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 256, - │ "time_to_first_token": 0, - │ "tokens": 1323 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 0, - "text": 12, - "total": 12 - }, - "raw": { - "completion_tokens": 12, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 0, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1099 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 0, - "completion_tokens": 12, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 0, - "time_to_first_token": 0, - "tokens": 1099 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.json deleted file mode 100644 index 300093d33..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.json +++ /dev/null @@ -1,736 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "finishReason": "tool-calls", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1042 - }, - "inputTokens": 1042, - "outputTokenDetails": { - "reasoningTokens": 192, - "textTokens": 24 - }, - "outputTokens": 216, - "raw": { - "completion_tokens": 216, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1258 - }, - "totalTokens": 1258 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 216, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "tokens": 1258 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "toolCallId": "", - "toolName": "lookup_weather" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.19.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2491 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.txt deleted file mode 100644 index 6b7ecae7a..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-auto.span-tree.txt +++ /dev/null @@ -1,716 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "cloudflare_think.version": "0.19.0", - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2491 - } - ├── doStream [llm] - │ input: { - │ "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "messages": [ - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "model": { - │ "modelId": "gpt-5-nano", - │ "provider": "openai.chat" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "content": [ - │ { - │ "input": { - │ "city": "Vienna" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "finishReason": "tool-calls", - │ "providerMetadata": { - │ "openai": { - │ "acceptedPredictionTokens": 0, - │ "rejectedPredictionTokens": 0 - │ } - │ }, - │ "response": { - │ "id": "" - │ }, - │ "usage": { - │ "inputTokenDetails": { - │ "cacheReadTokens": 0, - │ "noCacheTokens": 1042 - │ }, - │ "inputTokens": 1042, - │ "outputTokenDetails": { - │ "reasoningTokens": 192, - │ "textTokens": 24 - │ }, - │ "outputTokens": 216, - │ "raw": { - │ "completion_tokens": 216, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 192, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1258 - │ }, - │ "totalTokens": 1258 - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "functionId": "TestThink", - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_tokens": 216, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "tokens": 1258 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "toolCallId": "", - │ "toolName": "lookup_weather" - │ } - └── doStream [llm] - input: { - "instructions": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "messages": [ - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "model": { - "modelId": "gpt-5-nano", - "provider": "openai.chat" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "content": [ - { - "text": "Vienna is sunny and 21°C.", - "type": "text" - } - ], - "finishReason": "stop", - "providerMetadata": { - "openai": { - "acceptedPredictionTokens": 0, - "rejectedPredictionTokens": 0 - } - }, - "response": { - "id": "" - }, - "usage": { - "inputTokenDetails": { - "cacheReadTokens": 0, - "noCacheTokens": 1087 - }, - "inputTokens": 1087, - "outputTokenDetails": { - "reasoningTokens": 128, - "textTokens": 18 - }, - "outputTokens": 146, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - }, - "totalTokens": 1233 - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "functionId": "TestThink", - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.json b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.json deleted file mode 100644 index abba8a2b5..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.json +++ /dev/null @@ -1,919 +0,0 @@ -{ - "span_tree": [ - { - "name": "Think.runTurn", - "type": "task", - "children": [ - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "text": "", - "toolCalls": [ - { - "input": "{\"city\":\"Vienna\"}", - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1042, - "total": 1042 - }, - "outputTokens": { - "reasoning": 192, - "text": 24, - "total": 216 - }, - "raw": { - "completion_tokens": 216, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 192, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1042, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1258 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "tool_calls", - "unified": "tool-calls" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 192, - "completion_tokens": 216, - "prompt_cached_tokens": 0, - "prompt_tokens": 1042, - "reasoning_tokens": 192, - "time_to_first_token": 0, - "tokens": 1258 - } - }, - { - "name": "lookup_weather", - "type": "tool", - "children": [], - "input": { - "city": "Vienna" - }, - "output": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - }, - "metadata": { - "toolCallId": "" - } - }, - { - "name": "doStream", - "type": "llm", - "children": [], - "input": { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - }, - "output": { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - }, - "metadata": { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - }, - "metrics": { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } - } - ], - "input": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ], - "output": { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - }, - "metadata": { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - }, - "metrics": { - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2491 - } - } - ] -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.txt b/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.txt deleted file mode 100644 index c91b928b1..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__snapshots__/cloudflare-think-v0-19-latest-ai7-manual.span-tree.txt +++ /dev/null @@ -1,899 +0,0 @@ -span_tree: -└── Think.runTurn [task] - input: [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - } - ] - output: { - "content": "Vienna is sunny and 21°C.", - "role": "assistant" - } - metadata: { - "braintrust": { - "integration_name": "cloudflare-think", - "sdk_language": "typescript" - }, - "model": "gpt-5-nano", - "provider": "openai.chat", - "tools": { - "bash": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "type": "string" - }, - "script": { - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - } - }, - "delete": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "type": "string" - }, - "recursive": { - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "edit": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "type": "string" - }, - "old_string": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - } - }, - "find": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - } - }, - "grep": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "type": "boolean" - }, - "contextLines": { - "type": "number" - }, - "fixedString": { - "type": "boolean" - }, - "include": { - "type": "string" - }, - "query": { - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - } - }, - "list": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "default": "/", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "lookup_weather": { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - } - }, - "read": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - } - }, - "write": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "type": "string" - }, - "path": { - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - } - } - } - } - metrics: { - "completion_tokens": 362, - "prompt_cached_tokens": 0, - "prompt_tokens": 2129, - "time_to_first_token": 0, - "tokens": 2491 - } - ├── doStream [llm] - │ input: { - │ "abortSignal": "[AbortSignal]", - │ "includeRawChunks": false, - │ "prompt": [ - │ { - │ "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - │ "role": "system" - │ }, - │ { - │ "content": [ - │ { - │ "text": "What is the weather in Vienna?", - │ "type": "text" - │ } - │ ], - │ "role": "user" - │ } - │ ], - │ "toolChoice": { - │ "type": "auto" - │ }, - │ "tools": [ - │ { - │ "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Number of lines to read", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "1-indexed line number to start reading from", - │ "maximum": 9007199254740991, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "read", - │ "type": "function" - │ }, - │ { - │ "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "content": { - │ "description": "Content to write to the file", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "content" - │ ], - │ "type": "object" - │ }, - │ "name": "write", - │ "type": "function" - │ }, - │ { - │ "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "new_string": { - │ "description": "Replacement text", - │ "type": "string" - │ }, - │ "old_string": { - │ "description": "Exact text to find and replace. Empty string to create a new file.", - │ "type": "string" - │ }, - │ "path": { - │ "description": "Absolute path to the file", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "path", - │ "old_string", - │ "new_string" - │ ], - │ "type": "object" - │ }, - │ "name": "edit", - │ "type": "function" - │ }, - │ { - │ "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "limit": { - │ "description": "Maximum number of entries to return (default: 200)", - │ "maximum": 1000, - │ "minimum": 1, - │ "type": "integer" - │ }, - │ "offset": { - │ "description": "Number of entries to skip (for pagination)", - │ "maximum": 9007199254740991, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "path": { - │ "default": "/", - │ "description": "Absolute path to the directory to list", - │ "type": "string" - │ } - │ }, - │ "type": "object" - │ }, - │ "name": "list", - │ "type": "function" - │ }, - │ { - │ "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "pattern": { - │ "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "pattern" - │ ], - │ "type": "object" - │ }, - │ "name": "find", - │ "type": "function" - │ }, - │ { - │ "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "caseSensitive": { - │ "description": "If true, search is case-sensitive (default: false)", - │ "type": "boolean" - │ }, - │ "contextLines": { - │ "description": "Number of context lines around each match (default: 0)", - │ "maximum": 10, - │ "minimum": 0, - │ "type": "integer" - │ }, - │ "fixedString": { - │ "description": "If true, treat query as a literal string instead of regex", - │ "type": "boolean" - │ }, - │ "include": { - │ "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - │ "type": "string" - │ }, - │ "query": { - │ "description": "Search pattern (regex or fixed string)", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "query" - │ ], - │ "type": "object" - │ }, - │ "name": "grep", - │ "type": "function" - │ }, - │ { - │ "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "path": { - │ "description": "Absolute path to the file or directory", - │ "type": "string" - │ }, - │ "recursive": { - │ "description": "If true, remove directories and their contents recursively", - │ "type": "boolean" - │ } - │ }, - │ "required": [ - │ "path" - │ ], - │ "type": "object" - │ }, - │ "name": "delete", - │ "type": "function" - │ }, - │ { - │ "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "cwd": { - │ "description": "Working directory for the script. Defaults to / (the workspace root)", - │ "type": "string" - │ }, - │ "script": { - │ "description": "Bash script to run", - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "script" - │ ], - │ "type": "object" - │ }, - │ "name": "bash", - │ "type": "function" - │ }, - │ { - │ "description": "Get deterministic weather for a city.", - │ "inputSchema": { - │ "$schema": "http://json-schema.org/draft-07/schema#", - │ "additionalProperties": false, - │ "properties": { - │ "city": { - │ "type": "string" - │ } - │ }, - │ "required": [ - │ "city" - │ ], - │ "type": "object" - │ }, - │ "name": "lookup_weather", - │ "type": "function" - │ } - │ ] - │ } - │ output: { - │ "finishReason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "text": "", - │ "toolCalls": [ - │ { - │ "input": "{\"city\":\"Vienna\"}", - │ "toolCallId": "", - │ "toolName": "lookup_weather", - │ "type": "tool-call" - │ } - │ ], - │ "usage": { - │ "inputTokens": { - │ "cacheRead": 0, - │ "noCache": 1042, - │ "total": 1042 - │ }, - │ "outputTokens": { - │ "reasoning": 192, - │ "text": 24, - │ "total": 216 - │ }, - │ "raw": { - │ "completion_tokens": 216, - │ "completion_tokens_details": { - │ "accepted_prediction_tokens": 0, - │ "reasoning_tokens": 192, - │ "rejected_prediction_tokens": 0 - │ }, - │ "prompt_tokens": 1042, - │ "prompt_tokens_details": { - │ "cached_tokens": 0 - │ }, - │ "total_tokens": 1258 - │ } - │ } - │ } - │ metadata: { - │ "braintrust": { - │ "integration_name": "ai-sdk", - │ "sdk_language": "typescript" - │ }, - │ "finish_reason": { - │ "raw": "tool_calls", - │ "unified": "tool-calls" - │ }, - │ "model": "gpt-5-nano", - │ "provider": "openai.chat" - │ } - │ metrics: { - │ "completion_reasoning_tokens": 192, - │ "completion_tokens": 216, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 1042, - │ "reasoning_tokens": 192, - │ "time_to_first_token": 0, - │ "tokens": 1258 - │ } - ├── lookup_weather [tool] - │ input: { - │ "city": "Vienna" - │ } - │ output: { - │ "city": "Vienna", - │ "condition": "sunny", - │ "degreesC": 21 - │ } - │ metadata: { - │ "toolCallId": "" - │ } - └── doStream [llm] - input: { - "abortSignal": "[AbortSignal]", - "includeRawChunks": false, - "prompt": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "system" - }, - { - "content": [ - { - "text": "What is the weather in Vienna?", - "type": "text" - } - ], - "role": "user" - }, - { - "content": [ - { - "input": { - "city": "Vienna" - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-call" - } - ], - "role": "assistant" - }, - { - "content": [ - { - "output": { - "type": "json", - "value": { - "city": "Vienna", - "condition": "sunny", - "degreesC": 21 - } - }, - "toolCallId": "", - "toolName": "lookup_weather", - "type": "tool-result" - } - ], - "role": "tool" - } - ], - "toolChoice": { - "type": "auto" - }, - "tools": [ - { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "read", - "type": "function" - }, - { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "content" - ], - "type": "object" - }, - "name": "write", - "type": "function" - }, - { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": [ - "path", - "old_string", - "new_string" - ], - "type": "object" - }, - "name": "edit", - "type": "function" - }, - { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - }, - "name": "list", - "type": "function" - }, - { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": [ - "pattern" - ], - "type": "object" - }, - "name": "find", - "type": "function" - }, - { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": [ - "query" - ], - "type": "object" - }, - "name": "grep", - "type": "function" - }, - { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": [ - "path" - ], - "type": "object" - }, - "name": "delete", - "type": "function" - }, - { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": [ - "script" - ], - "type": "object" - }, - "name": "bash", - "type": "function" - }, - { - "description": "Get deterministic weather for a city.", - "inputSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": [ - "city" - ], - "type": "object" - }, - "name": "lookup_weather", - "type": "function" - } - ] - } - output: { - "finishReason": { - "raw": "stop", - "unified": "stop" - }, - "text": "Vienna is sunny and 21°C.", - "toolCalls": [], - "usage": { - "inputTokens": { - "cacheRead": 0, - "noCache": 1087, - "total": 1087 - }, - "outputTokens": { - "reasoning": 128, - "text": 18, - "total": 146 - }, - "raw": { - "completion_tokens": 146, - "completion_tokens_details": { - "accepted_prediction_tokens": 0, - "reasoning_tokens": 128, - "rejected_prediction_tokens": 0 - }, - "prompt_tokens": 1087, - "prompt_tokens_details": { - "cached_tokens": 0 - }, - "total_tokens": 1233 - } - } - } - metadata: { - "braintrust": { - "integration_name": "ai-sdk", - "sdk_language": "typescript" - }, - "finish_reason": { - "raw": "stop", - "unified": "stop" - }, - "model": "gpt-5-nano", - "provider": "openai.chat" - } - metrics: { - "completion_reasoning_tokens": 128, - "completion_tokens": 146, - "prompt_cached_tokens": 0, - "prompt_tokens": 1087, - "reasoning_tokens": 128, - "time_to_first_token": 0, - "tokens": 1233 - } diff --git a/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts b/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts index 8452a8557..780d32d38 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts +++ b/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts @@ -22,16 +22,12 @@ type ScenarioRunner = (harness: { export function defineCloudflareThinkAssertions(options: { name: string; runScenario: ScenarioRunner; - snapshotName: string; + snapshotName?: string; testFileUrl: string; timeoutMs: number; usesV7Telemetry: boolean; }): void { const timeoutMs = effectiveScenarioTimeoutMs(options.timeoutMs); - const snapshotPath = resolveFileSnapshotPath( - options.testFileUrl, - `${options.snapshotName}.span-tree.json`, - ); describe(options.name, () => { let events: CapturedLogEvent[] = []; @@ -133,6 +129,13 @@ export function defineCloudflareThinkAssertions(options: { }, ); + if (!options.snapshotName) { + return; + } + const snapshotPath = resolveFileSnapshotPath( + options.testFileUrl, + `${options.snapshotName}.span-tree.json`, + ); test("matches the span tree snapshot", { timeout: timeoutMs }, async () => { expect(setupError).toBeUndefined(); const names = new Set(["Think.runTurn", "doStream", "lookup_weather"]); diff --git a/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts b/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts index 4868551cf..96d600b16 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts +++ b/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts @@ -52,6 +52,7 @@ for (const aiMajor of [6, 7]) { ? "agents-v0-22" : "agents", dependencyName, + snapshot: minor === 13 || minor === 20, label: `0.${minor} ${lane} / AI SDK ${aiMajor}`, scenarioDir, variantKey: `${dependencyName}-ai${aiMajor}`, @@ -89,7 +90,9 @@ describeVariants("Cloudflare Think variants", () => { timeoutMs: TIMEOUT_MS, }); }, - snapshotName: `${variant.variantKey}-${mode}`, + snapshotName: variant.snapshot + ? `${variant.variantKey}-${mode}` + : undefined, testFileUrl: import.meta.url, timeoutMs: TIMEOUT_MS, }); From a7437ced9179bdea569981ca93e899bf296d5fb9 Mon Sep 17 00:00:00 2001 From: lforst <8118419+lforst@users.noreply.github.com> Date: Tue, 20 Oct 2026 17:46:07 +0000 Subject: [PATCH 4/4] Update PR #2640 --- e2e/README.md | 14 +- e2e/config/pr-comment-scenarios.json | 176 ----- e2e/helpers/cassette-audit.test.ts | 264 +++++++ e2e/helpers/scenario-harness.ts | 84 +-- e2e/package.json | 3 +- ...udflare-think-v0-14-ai6-auto.cassette.json | 645 ------------------ ...flare-think-v0-14-ai6-manual.cassette.json | 645 ------------------ ...-think-v0-14-latest-ai6-auto.cassette.json | 645 ------------------ ...hink-v0-14-latest-ai6-manual.cassette.json | 645 ------------------ ...udflare-think-v0-15-ai6-auto.cassette.json | 645 ------------------ ...flare-think-v0-15-ai6-manual.cassette.json | 645 ------------------ ...udflare-think-v0-15-ai7-auto.cassette.json | 645 ------------------ ...flare-think-v0-15-ai7-manual.cassette.json | 645 ------------------ ...-think-v0-15-latest-ai6-auto.cassette.json | 645 ------------------ ...hink-v0-15-latest-ai6-manual.cassette.json | 645 ------------------ ...-think-v0-15-latest-ai7-auto.cassette.json | 645 ------------------ ...hink-v0-15-latest-ai7-manual.cassette.json | 645 ------------------ ...udflare-think-v0-16-ai6-auto.cassette.json | 645 ------------------ ...flare-think-v0-16-ai6-manual.cassette.json | 645 ------------------ ...udflare-think-v0-16-ai7-auto.cassette.json | 645 ------------------ ...flare-think-v0-16-ai7-manual.cassette.json | 645 ------------------ ...-think-v0-16-latest-ai6-auto.cassette.json | 645 ------------------ ...hink-v0-16-latest-ai6-manual.cassette.json | 645 ------------------ ...-think-v0-16-latest-ai7-auto.cassette.json | 645 ------------------ ...hink-v0-16-latest-ai7-manual.cassette.json | 645 ------------------ ...udflare-think-v0-17-ai6-auto.cassette.json | 645 ------------------ ...flare-think-v0-17-ai6-manual.cassette.json | 645 ------------------ ...udflare-think-v0-17-ai7-auto.cassette.json | 645 ------------------ ...flare-think-v0-17-ai7-manual.cassette.json | 645 ------------------ ...-think-v0-17-latest-ai6-auto.cassette.json | 645 ------------------ ...hink-v0-17-latest-ai6-manual.cassette.json | 645 ------------------ ...-think-v0-17-latest-ai7-auto.cassette.json | 645 ------------------ ...hink-v0-17-latest-ai7-manual.cassette.json | 645 ------------------ ...udflare-think-v0-18-ai6-auto.cassette.json | 645 ------------------ ...flare-think-v0-18-ai6-manual.cassette.json | 645 ------------------ ...udflare-think-v0-18-ai7-auto.cassette.json | 645 ------------------ ...flare-think-v0-18-ai7-manual.cassette.json | 645 ------------------ ...-think-v0-18-latest-ai6-auto.cassette.json | 645 ------------------ ...hink-v0-18-latest-ai6-manual.cassette.json | 645 ------------------ ...-think-v0-18-latest-ai7-auto.cassette.json | 645 ------------------ ...hink-v0-18-latest-ai7-manual.cassette.json | 645 ------------------ ...udflare-think-v0-19-ai6-auto.cassette.json | 645 ------------------ ...flare-think-v0-19-ai6-manual.cassette.json | 645 ------------------ ...udflare-think-v0-19-ai7-auto.cassette.json | 645 ------------------ ...flare-think-v0-19-ai7-manual.cassette.json | 645 ------------------ ...-think-v0-19-latest-ai6-auto.cassette.json | 645 ------------------ ...hink-v0-19-latest-ai6-manual.cassette.json | 645 ------------------ ...-think-v0-19-latest-ai7-auto.cassette.json | 645 ------------------ ...hink-v0-19-latest-ai7-manual.cassette.json | 645 ------------------ .../assertions.ts | 13 +- .../package.json | 66 -- .../scenario.test.ts | 61 +- .../versions/ai6/package.json | 16 +- .../versions/ai6/pnpm-lock.yaml | 546 --------------- .../versions/ai7/package.json | 14 +- .../versions/ai7/pnpm-lock.yaml | 586 +--------------- e2e/scripts/cassette-audit.mjs | 129 ++++ e2e/scripts/run-e2e-tests.mjs | 72 +- e2e/scripts/run-record-tests.mjs | 146 +--- package.json | 3 +- 60 files changed, 571 insertions(+), 30002 deletions(-) create mode 100644 e2e/helpers/cassette-audit.test.ts delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-manual.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-auto.cassette.json delete mode 100644 e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-manual.cassette.json create mode 100644 e2e/scripts/cassette-audit.mjs diff --git a/e2e/README.md b/e2e/README.md index f1ebcbecb..de605a69b 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -183,7 +183,19 @@ pnpm --filter=@braintrust/js-e2e-tests run test:e2e If a scenario records but later replay fails because of volatile fields in the request body (e.g. AI-SDK's generated message ids), add or update `/cassette-filter.mjs` for that scenario, then re-record. -After any successful record run, stale cassette variants are cleaned only inside scenarios that emitted cassette run-context records during that run. With explicit scenario names, cleanup is limited to those scenarios; with a full record run, cleanup applies to every observed cassette-backed scenario. Per-cassette blob sidecar cleanup still happens in the cassette file store when each cassette is saved. +After a successful record run, unused cassette variants and their blob directories are cleaned only for scenarios whose test files and tests all passed. Cleanup uses the cassette keys actually selected by the harness, including overrides and opt-outs. Scenarios with skipped tests, missing test files, or missing usage records are left untouched. Per-cassette blob sidecar cleanup still happens in the cassette file store when each cassette is saved. + +### Checking unused cassettes without re-recording + +```bash +pnpm run test:e2e:cassettes +pnpm run test:e2e:cassettes -- cloudflare-think-instrumentation +pnpm run test:e2e:cassettes -- --clean-cassettes cloudflare-think-instrumentation +``` + +These commands run a fresh replay and compare the cassette files on disk with actual usage. The default check leaves files untouched and exits nonzero when it finds unused variants. `--clean-cassettes` removes unused JSON files and their `.cassette.blobs` directories after the tests pass. + +Only whole scenarios can be selected; test filters, file paths, sharding, and snapshot updates are rejected. A scenario with skipped tests, missing test files, or missing usage records is reported as not checked and makes the command exit nonzero. Unselected scenarios and directories with no test files are not checked. Use `BRAINTRUST_E2E_RUN_CONTEXT_DIR` to retain the run records and test report for the trace summary. ### In-scope scenarios diff --git a/e2e/config/pr-comment-scenarios.json b/e2e/config/pr-comment-scenarios.json index d4d7a12e1..94165c4e7 100644 --- a/e2e/config/pr-comment-scenarios.json +++ b/e2e/config/pr-comment-scenarios.json @@ -170,182 +170,6 @@ "cloudflare-think-v0-13-latest-ai6-auto" ] }, - { - "variantKey": "cloudflare-think-v0-14-ai6", - "label": "v0.14 pinned / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-14-ai6-manual", - "cloudflare-think-v0-14-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-14-latest-ai6", - "label": "v0.14 latest / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-14-latest-ai6-manual", - "cloudflare-think-v0-14-latest-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-15-ai6", - "label": "v0.15 pinned / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-15-ai6-manual", - "cloudflare-think-v0-15-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-15-latest-ai6", - "label": "v0.15 latest / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-15-latest-ai6-manual", - "cloudflare-think-v0-15-latest-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-16-ai6", - "label": "v0.16 pinned / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-16-ai6-manual", - "cloudflare-think-v0-16-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-16-latest-ai6", - "label": "v0.16 latest / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-16-latest-ai6-manual", - "cloudflare-think-v0-16-latest-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-17-ai6", - "label": "v0.17 pinned / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-17-ai6-manual", - "cloudflare-think-v0-17-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-17-latest-ai6", - "label": "v0.17 latest / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-17-latest-ai6-manual", - "cloudflare-think-v0-17-latest-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-18-ai6", - "label": "v0.18 pinned / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-18-ai6-manual", - "cloudflare-think-v0-18-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-18-latest-ai6", - "label": "v0.18 latest / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-18-latest-ai6-manual", - "cloudflare-think-v0-18-latest-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-19-ai6", - "label": "v0.19 pinned / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-19-ai6-manual", - "cloudflare-think-v0-19-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-19-latest-ai6", - "label": "v0.19 latest / AI SDK 6", - "variantKeys": [ - "cloudflare-think-v0-19-latest-ai6-manual", - "cloudflare-think-v0-19-latest-ai6-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-15-ai7", - "label": "v0.15 pinned / AI SDK 7", - "variantKeys": [ - "cloudflare-think-v0-15-ai7-manual", - "cloudflare-think-v0-15-ai7-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-15-latest-ai7", - "label": "v0.15 latest / AI SDK 7", - "variantKeys": [ - "cloudflare-think-v0-15-latest-ai7-manual", - "cloudflare-think-v0-15-latest-ai7-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-16-ai7", - "label": "v0.16 pinned / AI SDK 7", - "variantKeys": [ - "cloudflare-think-v0-16-ai7-manual", - "cloudflare-think-v0-16-ai7-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-16-latest-ai7", - "label": "v0.16 latest / AI SDK 7", - "variantKeys": [ - "cloudflare-think-v0-16-latest-ai7-manual", - "cloudflare-think-v0-16-latest-ai7-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-17-ai7", - "label": "v0.17 pinned / AI SDK 7", - "variantKeys": [ - "cloudflare-think-v0-17-ai7-manual", - "cloudflare-think-v0-17-ai7-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-17-latest-ai7", - "label": "v0.17 latest / AI SDK 7", - "variantKeys": [ - "cloudflare-think-v0-17-latest-ai7-manual", - "cloudflare-think-v0-17-latest-ai7-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-18-ai7", - "label": "v0.18 pinned / AI SDK 7", - "variantKeys": [ - "cloudflare-think-v0-18-ai7-manual", - "cloudflare-think-v0-18-ai7-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-18-latest-ai7", - "label": "v0.18 latest / AI SDK 7", - "variantKeys": [ - "cloudflare-think-v0-18-latest-ai7-manual", - "cloudflare-think-v0-18-latest-ai7-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-19-ai7", - "label": "v0.19 pinned / AI SDK 7", - "variantKeys": [ - "cloudflare-think-v0-19-ai7-manual", - "cloudflare-think-v0-19-ai7-auto" - ] - }, - { - "variantKey": "cloudflare-think-v0-19-latest-ai7", - "label": "v0.19 latest / AI SDK 7", - "variantKeys": [ - "cloudflare-think-v0-19-latest-ai7-manual", - "cloudflare-think-v0-19-latest-ai7-auto" - ] - }, { "variantKey": "cloudflare-think-v0-20-ai7", "label": "v0.20 pinned / AI SDK 7", diff --git a/e2e/helpers/cassette-audit.test.ts b/e2e/helpers/cassette-audit.test.ts new file mode 100644 index 000000000..32c84e260 --- /dev/null +++ b/e2e/helpers/cassette-audit.test.ts @@ -0,0 +1,264 @@ +import { execFile } from "node:child_process"; +import { + mkdir, + mkdtemp, + readFile, + readdir, + rm, + writeFile, +} from "node:fs/promises"; +import { tmpdir } from "node:os"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { promisify } from "node:util"; +import { afterEach, beforeEach, expect, it, vi } from "vitest"; +import { auditCassettes } from "../scripts/cassette-audit.mjs"; +import { withScenarioHarness } from "./scenario-harness"; + +let dir: string; +let cassetteDir: string; +let contextDir: string; +let reportPath: string; +let report: { + success: boolean; + numFailedTests: number; + numFailedTestSuites: number; + testResults: { + name: string; + status: string; + assertionResults: { status: string }[]; + }[]; +}; + +beforeEach(async () => { + dir = await mkdtemp(path.join(tmpdir(), "braintrust-cassette-audit-")); + cassetteDir = path.join(dir, "scenarios", "selected", "__cassettes__"); + contextDir = path.join(dir, "context"); + reportPath = path.join(dir, "results.json"); + await mkdir(cassetteDir, { recursive: true }); + await mkdir(contextDir); + const testFile = path.join(dir, "scenarios", "selected", "scenario.test.ts"); + await writeFile(testFile, ""); + for (const key of ["actual", "default", "display", "stale"]) { + await writeFile(path.join(cassetteDir, `${key}.cassette.json`), "{}"); + await mkdir(path.join(cassetteDir, `${key}.cassette.blobs`)); + await writeFile( + path.join(cassetteDir, `${key}.cassette.blobs`, "blob"), + "bytes", + ); + } + await mkdir(path.join(cassetteDir, "orphan.cassette.blobs")); + await writeFile(path.join(cassetteDir, "notes.txt"), "keep"); + const otherDir = path.join(dir, "scenarios", "unselected", "__cassettes__"); + await mkdir(otherDir, { recursive: true }); + await writeFile(path.join(otherDir, "other.cassette.json"), "{}"); + await writeFile(path.join(otherDir, "..", "scenario.test.ts"), ""); + report = { + success: true, + numFailedTests: 0, + numFailedTestSuites: 0, + testResults: [ + { + name: testFile, + status: "passed", + assertionResults: [{ status: "passed" }], + }, + ], + }; + await writeFile(reportPath, JSON.stringify(report)); + await writeFile( + path.join(contextDir, "run-context-1.ndjson"), + [ + { + scenarioDirName: "selected", + variantKey: "display", + cassetteVariantKey: "actual", + }, + { scenarioDirName: "selected", cassetteVariantKey: "default" }, + { + scenarioDirName: "selected", + variantKey: "stale", + cassetteVariantKey: null, + }, + ] + .map((record) => JSON.stringify(record)) + .join("\n"), + ); +}); + +afterEach(async () => { + vi.unstubAllEnvs(); + await rm(dir, { recursive: true, force: true }); +}); + +it("records resolved cassette usage for expected failures and explicit opt-outs", async () => { + vi.stubEnv("BRAINTRUST_E2E_RUN_CONTEXT_DIR", contextDir); + vi.stubEnv("BRAINTRUST_E2E_CASSETTE_MODE", "replay"); + const scenarioDir = path.dirname(cassetteDir); + await writeFile( + path.join(scenarioDir, "failure.mjs"), + "process.exitCode = 1;", + ); + await writeFile(path.join(scenarioDir, "success.mjs"), ""); + await withScenarioHarness( + async (harness) => { + await expect( + harness.runNodeScenarioDir({ + scenarioDir, + entry: "failure.mjs", + runContext: { + originalScenarioDir: scenarioDir, + variantKey: "display", + cassette: { variantKey: "expected-error" }, + }, + }), + ).rejects.toThrow(); + await harness.runNodeScenarioDir({ + scenarioDir, + entry: "success.mjs", + runContext: { + originalScenarioDir: scenarioDir, + variantKey: "actual", + cassette: false, + }, + }); + }, + { forwardToProduction: false }, + ); + const records = ( + await readFile( + path.join(contextDir, `run-context-${process.pid}.ndjson`), + "utf8", + ) + ) + .trim() + .split("\n") + .map((line) => JSON.parse(line)); + expect(records).toMatchObject([ + { variantKey: "display", cassetteVariantKey: "expected-error" }, + { variantKey: "actual", cassetteVariantKey: null }, + ]); +}); + +it("reports unused variants using actual cassette keys without deleting files", async () => { + const before = await readdir(cassetteDir); + const result = await auditCassettes({ + e2eDir: dir, + runContextDir: contextDir, + reportPath, + }); + expect( + result.unused.map((entry: { variantKey: string }) => entry.variantKey), + ).toEqual(["display", "orphan", "stale"]); + expect(result.skipped).toEqual([]); + expect(await readdir(cassetteDir)).toEqual(before); +}); + +it("cleans unused JSON and blob artifacts while preserving used and unselected fixtures", async () => { + await auditCassettes({ + e2eDir: dir, + runContextDir: contextDir, + reportPath, + clean: true, + }); + expect((await readdir(cassetteDir)).sort()).toEqual([ + "actual.cassette.blobs", + "actual.cassette.json", + "default.cassette.blobs", + "default.cassette.json", + "notes.txt", + ]); + expect( + await readFile( + path.join(cassetteDir, "actual.cassette.blobs", "blob"), + "utf8", + ), + ).toBe("bytes"); + expect( + await readFile( + path.join( + dir, + "scenarios", + "unselected", + "__cassettes__", + "other.cassette.json", + ), + "utf8", + ), + ).toBe("{}"); +}); + +it.each(["skipped", "missing file", "no records"])( + "preserves a scenario with %s coverage", + async (mode) => { + if (mode === "skipped") { + report.testResults[0].assertionResults.push({ status: "pending" }); + await writeFile(reportPath, JSON.stringify(report)); + } else if (mode === "missing file") { + await writeFile(path.join(cassetteDir, "..", "other.test.ts"), ""); + } else { + await rm(path.join(contextDir, "run-context-1.ndjson")); + } + const before = await readdir(cassetteDir); + const result = await auditCassettes({ + e2eDir: dir, + runContextDir: contextDir, + reportPath, + clean: true, + }); + expect(result.unused).toEqual([]); + expect(result.skipped).toEqual(["selected"]); + expect(await readdir(cassetteDir)).toEqual(before); + }, +); + +it("refuses cleanup after a failed run", async () => { + report.success = false; + report.numFailedTests = 1; + await writeFile(reportPath, JSON.stringify(report)); + const before = await readdir(cassetteDir); + await expect( + auditCassettes({ + e2eDir: dir, + runContextDir: contextDir, + reportPath, + clean: true, + }), + ).rejects.toThrow("successful, complete test report"); + expect(await readdir(cassetteDir)).toEqual(before); +}); + +it.each(["{broken", '{"scenarioDirName":"selected","variantKey":"actual"}'])( + "rejects malformed or legacy usage records before deleting anything", + async (record) => { + await writeFile(path.join(contextDir, "run-context-2.ndjson"), record); + const before = await readdir(cassetteDir); + await expect( + auditCassettes({ + e2eDir: dir, + runContextDir: contextDir, + reportPath, + clean: true, + }), + ).rejects.toThrow(); + expect(await readdir(cassetteDir)).toEqual(before); + }, +); + +it.each([ + ["--check-cassettes", "-t", "one-test"], + ["--clean-cassettes", "--shard=1/2"], + ["--check-cassettes", "scenarios/selected/scenario.test.ts"], + ["--check-cassettes", "--update"], + ["--check-cassettes", "nonexistent-scenario"], +])("rejects partial audit arguments %j", async (...args) => { + await expect( + promisify(execFile)(process.execPath, [ + fileURLToPath(new URL("../scripts/run-e2e-tests.mjs", import.meta.url)), + ...args, + ]), + ).rejects.toMatchObject({ + code: 1, + stderr: expect.stringContaining("Select whole scenarios by name"), + }); +}); diff --git a/e2e/helpers/scenario-harness.ts b/e2e/helpers/scenario-harness.ts index 93164bca2..8f5f9db41 100644 --- a/e2e/helpers/scenario-harness.ts +++ b/e2e/helpers/scenario-harness.ts @@ -81,6 +81,7 @@ export interface ScenarioRunContext { } interface ScenarioRunContextRecord { + cassetteVariantKey: string | null; forwardToProduction?: boolean; logRootSpanIds: string[]; experimentNames: string[]; @@ -790,15 +791,9 @@ export async function withScenarioHarness( }; const runWithCassetteServer = async ( - options: { - entry?: string; - env?: Record; - runContext?: ScenarioRunContext; - scenarioDir: string; - }, + wiring: CassetteWiring | null, run: (cassetteEnv: Record) => Promise, ): Promise => { - const wiring = cassetteWiringFor(options); if (!wiring) { return await run({}); } @@ -853,39 +848,44 @@ export async function withScenarioHarness( }, runner: ScenarioRunner, defaultEntry: string, - run: () => Promise, + run: (wiring: CassetteWiring | null) => Promise, ): Promise => { - const result = await run(); - await recordScenarioRunContext({ - forwardToProduction: prodForwarding !== null, - logRootSpanIds: [ - ...new Set( - [ - ...server.events - .filter((event) => !event.experimentId) - .map((event) => event.span.rootId), - ...server.requests - .filter((request) => request.path === "/otel/v1/traces") - .flatMap((request) => extractOtelSpans(request.jsonBody)) - .map((span) => span.traceId), - ].filter((id): id is string => typeof id === "string"), + const wiring = runner === "deno" ? null : cassetteWiringFor(options); + try { + return await run(wiring); + } finally { + // Expected failures can still consume a cassette. Keep that usage too. + await recordScenarioRunContext({ + cassetteVariantKey: wiring?.variantKey ?? null, + forwardToProduction: prodForwarding !== null, + logRootSpanIds: [ + ...new Set( + [ + ...server.events + .filter((event) => !event.experimentId) + .map((event) => event.span.rootId), + ...server.requests + .filter((request) => request.path === "/otel/v1/traces") + .flatMap((request) => extractOtelSpans(request.jsonBody)) + .map((span) => span.traceId), + ].filter((id): id is string => typeof id === "string"), + ), + ], + experimentNames: server.experiments + .filter((experiment) => + server.events.some((event) => event.experimentId === experiment.id), + ) + .map((experiment) => experiment.name), + entry: options.entry ?? defaultEntry, + runner, + scenarioDirName: path.basename( + options.runContext?.originalScenarioDir ?? options.scenarioDir, ), - ], - experimentNames: server.experiments - .filter((experiment) => - server.events.some((event) => event.experimentId === experiment.id), - ) - .map((experiment) => experiment.name), - entry: options.entry ?? defaultEntry, - runner, - scenarioDirName: path.basename( - options.runContext?.originalScenarioDir ?? options.scenarioDir, - ), - testRunId, - timestamp: new Date().toISOString(), - variantKey: options.runContext?.variantKey, - }); - return result; + testRunId, + timestamp: new Date().toISOString(), + variantKey: options.runContext?.variantKey, + }); + } }; try { @@ -908,8 +908,8 @@ export async function withScenarioHarness( }), ), runNodeScenarioDir: (options) => - runWithContext(options, "node", "scenario.mjs", async () => - runWithCassetteServer(options, (cassetteEnv) => + runWithContext(options, "node", "scenario.mjs", async (wiring) => + runWithCassetteServer(wiring, (cassetteEnv) => runNodeScenarioDir({ ...options, env: { @@ -921,8 +921,8 @@ export async function withScenarioHarness( ), ), runScenarioDir: (options) => - runWithContext(options, "tsx", "scenario.ts", async () => - runWithCassetteServer(options, (cassetteEnv) => + runWithContext(options, "tsx", "scenario.ts", async (wiring) => + runWithCassetteServer(wiring, (cassetteEnv) => runScenarioDir({ ...options, env: { diff --git a/e2e/package.json b/e2e/package.json index e10636749..cb9ad5d74 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -5,7 +5,8 @@ "scripts": { "test:e2e": "node ./scripts/run-e2e-tests.mjs", "test:e2e:update": "node ./scripts/run-e2e-tests.mjs --update", - "test:e2e:record": "node ./scripts/run-record-tests.mjs" + "test:e2e:record": "node ./scripts/run-record-tests.mjs", + "test:e2e:cassettes": "node ./scripts/run-e2e-tests.mjs --check-cassettes" }, "devDependencies": { "@braintrust/deepseek-harness": "workspace:^", diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-auto.cassette.json deleted file mode 100644 index ee6eb670c..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:07:04.280Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_WntIrLs2z7SHz7NmKcGeddJh\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DwMXJ7AB3sCEs\"}", - "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-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\":\"OutVzXa6Aa\"}", - "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jbJBo4ChU\"}", - "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-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\":\"nOnFhp6C\"}", - "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1zr3TEpf3\"}", - "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OtVRNWO2hls\"}", - "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-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\":\"6odyylcj6Y\"}", - "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"BTeG0IMEtUW\"}", - "data: {\"id\":\"chatcmpl-Eb12E4rpbTHN35QzUUOQTI1NblI0I\",\"object\":\"chat.completion.chunk\",\"created\":1792490822,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"IRVDLbojf4XS2Q6\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73694ab2f285a-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:07:04 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2146", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_ce630892ad294b019a6d250b82654d2e" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "6601b126a8bbb941", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:07:06.318Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_WntIrLs2z7SHz7NmKcGeddJh", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_WntIrLs2z7SHz7NmKcGeddJh" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JHFbH\"}", - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RpV\"}", - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Chvtp\"}", - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DEQk\"}", - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"o\"}", - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i7C\"}", - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RXbEC2\"}", - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ryvuE\"}", - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4CnNJ\"}", - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TFKfTA\"}", - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"N\"}", - "data: {\"id\":\"chatcmpl-Eb12G71JkDmJjnB6zLko1vIhhbLSy\",\"object\":\"chat.completion.chunk\",\"created\":1792490824,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"cEccvG0BXtacONI\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d736a43e9e285a-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:07:06 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1590", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_3a68223d8ae44ee5a02b3a5a5365f478" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:38.885Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-manual.cassette.json deleted file mode 100644 index 5c7fadb1b..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:06:51.969Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_jL3QS5Uw10fIKo573IaoJyNd\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"amPLE6qGZ83xm\"}", - "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-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\":\"1wCf9iAHsb\"}", - "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Zi0JPJeDd\"}", - "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-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\":\"e0Tt89Gc\"}", - "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sW7VQZxwi\"}", - "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZA8kPiJGViD\"}", - "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-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\":\"PQzdmYjhTq\"}", - "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"csETsQd7i8Q\"}", - "data: {\"id\":\"chatcmpl-Eb121ZnxubHFM9Ti6rtnSqVtqzZSV\",\"object\":\"chat.completion.chunk\",\"created\":1792490809,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":408,\"total_tokens\":1450,\"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\":\"hwzwVXqNJGLHkds\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73642bead5c46-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:06:51 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2826", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_5e405fd9ea354369ae4bd05f6319629d" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "a99b09a9027c25e7", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:06:53.944Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_jL3QS5Uw10fIKo573IaoJyNd", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_jL3QS5Uw10fIKo573IaoJyNd" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XgIEo\"}", - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1Mc\"}", - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"IgeeS\"}", - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i8eH\"}", - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"e\"}", - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"f5e\"}", - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"yLllvW\"}", - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5K3Sb\"}", - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EFoqz\"}", - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"b4XCLk\"}", - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"s\"}", - "data: {\"id\":\"chatcmpl-Eb124BJSiqd7fTKJxbilOrDDjZ6F4\",\"object\":\"chat.completion.chunk\",\"created\":1792490812,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"26DejGyhx8lzZUr\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d736572e035c46-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:06:53 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1568", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_92baae7fdb9440c48f62e3f4639f9480" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:36.406Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-auto.cassette.json deleted file mode 100644 index c3771303d..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:07:27.498Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_Fy7dnfNrX4wpSdBmqSZewows\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ONon663AzIDhr\"}", - "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-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\":\"ZI12ll4qAt\"}", - "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cawWXGA2K\"}", - "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-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\":\"tyFD2ja8\"}", - "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"O8LUlfIFl\"}", - "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"veTn2H6YhHg\"}", - "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-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\":\"x4rcdgXHSd\"}", - "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"RALZDT8kDbD\"}", - "data: {\"id\":\"chatcmpl-Eb12b4scKvs55VqJW0Kz44PKgzCLC\",\"object\":\"chat.completion.chunk\",\"created\":1792490845,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"ddLXkhhSFHD8N7R\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d737251a8d9f0b-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:07:27 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2220", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_7c700d5ed8d247a58a005872f8e0945a" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "536e62020edfbe2d", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:07:28.239Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_Fy7dnfNrX4wpSdBmqSZewows", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_Fy7dnfNrX4wpSdBmqSZewows" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VLPOG\"}", - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"W3s\"}", - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3nNac\"}", - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nNbL\"}", - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"C\"}", - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ifj\"}", - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wHe6Lx\"}", - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FKOxr\"}", - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gw76L\"}", - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dh0sSa\"}", - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"M\"}", - "data: {\"id\":\"chatcmpl-Eb12dcvy6tyjr25GeJwHQ4KS5IYo4\",\"object\":\"chat.completion.chunk\",\"created\":1792490847,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":12,\"total_tokens\":1099,\"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\":\"XS\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73735490f9f0b-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:07:28 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "261", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_f77442da99d74671be82af7f414a1114" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:42.847Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-manual.cassette.json deleted file mode 100644 index b70a7e30e..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-14-latest-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:07:16.914Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_S2jmaDTpfK7KQxjcJVppe4oM\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mipPsYzjtQJmX\"}", - "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-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\":\"5f2v8IbaHF\"}", - "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PE81YwnOR\"}", - "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-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\":\"PRQnKOe2\"}", - "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"oCLZjcOFj\"}", - "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"l218J0J8jfa\"}", - "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-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\":\"WFRh8u533M\"}", - "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"Z1nGKhFdrxK\"}", - "data: {\"id\":\"chatcmpl-Eb12RNokyvFQOhWnsUbOfPpnHw6Va\",\"object\":\"chat.completion.chunk\",\"created\":1792490835,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"t2dXfKZAzZQo2dI\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d736e5addd5925-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:07:16 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1810", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_734d3231cd4d4c84a025a99f1a5a83da" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "6582b413e162207c", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:07:17.614Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_S2jmaDTpfK7KQxjcJVppe4oM", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_S2jmaDTpfK7KQxjcJVppe4oM" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PyT99\"}", - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Haq\"}", - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5euWl\"}", - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OShI\"}", - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"X\"}", - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9fD\"}", - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"czvcmC\"}", - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uzZqz\"}", - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"y23iW\"}", - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tpr5A2\"}", - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"j\"}", - "data: {\"id\":\"chatcmpl-Eb12TTk3tZfJpNYUd2xmbFwWaiCQJ\",\"object\":\"chat.completion.chunk\",\"created\":1792490837,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":12,\"total_tokens\":1099,\"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\":\"1i\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d736f30c4a5925-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:07:17 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "303", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_e36d9c1924ba4717b1280a182032fb2a" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:40.624Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-auto.cassette.json deleted file mode 100644 index 1c3e29138..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:07:57.109Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_8PnGbmPhJTaq74kxntGSfTNS\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Jbbnl7Lfeyazy\"}", - "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-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\":\"xKjZfAe30Z\"}", - "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6tBAIGpiy\"}", - "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-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\":\"ifU7vApF\"}", - "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"41uXlwoqY\"}", - "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"G3hMQG5VIM0\"}", - "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-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\":\"26LQovFCic\"}", - "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"jo3npxv0UNI\"}", - "data: {\"id\":\"chatcmpl-Eb132u8R2B4F7e2Qu1wmw5KczG31P\",\"object\":\"chat.completion.chunk\",\"created\":1792490872,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":472,\"total_tokens\":1514,\"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\":\"Y1Zabh92MDqSBmT\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d737d0ba1c2a41-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:07:57 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "4401", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_0d50b353c30e4a1795a500e58a6e99a9" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "014d6609e3bdf228", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:07:58.681Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_8PnGbmPhJTaq74kxntGSfTNS", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_8PnGbmPhJTaq74kxntGSfTNS" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EGkOV\"}", - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4WN\"}", - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xs3oo\"}", - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mUOp\"}", - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"M\"}", - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WFe\"}", - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"D3ew3i\"}", - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dkRc4\"}", - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tXv8i\"}", - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HBCr9w\"}", - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"z\"}", - "data: {\"id\":\"chatcmpl-Eb137Mlyq96H7FIKwN4WvynUvu815\",\"object\":\"chat.completion.chunk\",\"created\":1792490877,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":82,\"total_tokens\":1169,\"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\":\"D\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d737ee4d502a41-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:07:58 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1197", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_fc39267ea33a4297bb54d05fd64e30ec" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:46.525Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-manual.cassette.json deleted file mode 100644 index 09101b64c..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:07:41.291Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_5sJ3ggTZXX0MgY7V0DEerfyu\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"CKfXZ2C3TFiYH\"}", - "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-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\":\"QRxixMB9VP\"}", - "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vwbCmeaKl\"}", - "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-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\":\"CRaheg5f\"}", - "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7Hz2AgaDP\"}", - "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lFI1Na3lhaS\"}", - "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-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\":\"bSAfktUZ8l\"}", - "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"oyGjeX43yv7\"}", - "data: {\"id\":\"chatcmpl-Eb12oPI87dVsjhleoUOxm4e5vjSFG\",\"object\":\"chat.completion.chunk\",\"created\":1792490858,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"oONvOX2nU54xcS6\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d737763d13f5e7-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:07:41 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3009", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_ec039d1dd52d4c419890c9227d1ecf5d" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "2358d1a0d54080ca", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:07:43.769Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_5sJ3ggTZXX0MgY7V0DEerfyu", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_5sJ3ggTZXX0MgY7V0DEerfyu" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sN5Jt\"}", - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zc2\"}", - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zCUQQ\"}", - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"m668\"}", - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"s\"}", - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7oX\"}", - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"CpmiUY\"}", - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cSA0i\"}", - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5xlie\"}", - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XjlD0j\"}", - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"1\"}", - "data: {\"id\":\"chatcmpl-Eb12rZSR2THJXj0KVSMOwmhwaM8Cj\",\"object\":\"chat.completion.chunk\",\"created\":1792490861,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"g8KJl9aR78qBsf2\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d7378da8e3f5e7-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:07:43 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1776", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_550d7558803c464894666c310058d235" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:44.569Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-auto.cassette.json deleted file mode 100644 index 488d6e0e3..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:10:14.813Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_gpZJTMgposhEGy6FQcWKr6Nr\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gvBEsOWSOjvi1\"}", - "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-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\":\"PzuzR5u4Y4\"}", - "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"QKFueB3Yy\"}", - "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-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\":\"Z0kKqCi1\"}", - "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OwTTDxCZy\"}", - "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6lwArIRQbDR\"}", - "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-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\":\"cZEXiMQd5x\"}", - "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"jhIfv0Huo8E\"}", - "data: {\"id\":\"chatcmpl-Eb15I3ElQchjCZOlJUgiAXdjw9nJ3\",\"object\":\"chat.completion.chunk\",\"created\":1792491012,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"G5XjoIGzKsXrhaA\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73b3b6ab15671-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:10:14 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2160", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_45d4c91efcd44077b0019bbf78deca33" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "1901af6f191db57b", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:10:16.957Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_gpZJTMgposhEGy6FQcWKr6Nr", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_gpZJTMgposhEGy6FQcWKr6Nr" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2hwrG\"}", - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Soy\"}", - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hyoAn\"}", - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KOFH\"}", - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"I\"}", - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Ldn\"}", - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"NHcYI0\"}", - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Rjf6U\"}", - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HEYa9\"}", - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LGsmdr\"}", - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"t\"}", - "data: {\"id\":\"chatcmpl-Eb15L3AHPGmjLlIwBoM7SCSaReXs9\",\"object\":\"chat.completion.chunk\",\"created\":1792491015,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"hT9ZYvgW0Vf3rTJ\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73b4ade4e5671-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:10:16 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1799", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_857a472480f44f9da6a7a3baa378600b" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:01.626Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-manual.cassette.json deleted file mode 100644 index eae78406e..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-ai7-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:10:04.387Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_2sQ4szXYNBlGMYfAGU0mE2hz\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"f1sDP2ejLkkKa\"}", - "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-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\":\"ZIHMjp8vld\"}", - "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"d5rXUL7Qd\"}", - "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-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\":\"03C7pNjz\"}", - "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JbzxifZwq\"}", - "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tLlMPLTZHD3\"}", - "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-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\":\"7HQ5ar1mVC\"}", - "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"QSTL36BeEPh\"}", - "data: {\"id\":\"chatcmpl-Eb157lUb24jVMSf7Qn5UP8QOIazAZ\",\"object\":\"chat.completion.chunk\",\"created\":1792491001,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"kZe8aq7ckRPqjjj\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73af488f6595b-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:10:04 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3051", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_ba68a241c52b44919d3ca482993ad01a" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "37bca3468bb735fe", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:10:04.983Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_2sQ4szXYNBlGMYfAGU0mE2hz", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_2sQ4szXYNBlGMYfAGU0mE2hz" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DsPUb\"}", - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kX6\"}", - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"naMvK\"}", - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"su4j\"}", - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Z\"}", - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jIq\"}", - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9PGtmK\"}", - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"GcfLc\"}", - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5CsSF\"}", - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eKbeYJ\"}", - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"A\"}", - "data: {\"id\":\"chatcmpl-Eb15ATNXwnMvCxuaw1A4fkCJGVxhJ\",\"object\":\"chat.completion.chunk\",\"created\":1792491004,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":12,\"total_tokens\":1099,\"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\":\"HX\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73b09cf08595b-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:10:04 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "251", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_46d964cec48b4c7f8770ffe225379bad" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:59:59.395Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-auto.cassette.json deleted file mode 100644 index 734868893..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:12:53.459Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_muWWJ3dJhjQZWwre0OGM51I5\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RE3rvhiYaqfvq\"}", - "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-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\":\"Oeqh1u98lm\"}", - "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pnikdeY18\"}", - "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-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\":\"ZBLAjTfk\"}", - "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"aMOCHPAAM\"}", - "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"QAHW6sre0wC\"}", - "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-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\":\"6dQvIA575j\"}", - "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"CS88OmTy1p1\"}", - "data: {\"id\":\"chatcmpl-Eb17qlSYsk1WYB8jUMFi1ZkTZslrB\",\"object\":\"chat.completion.chunk\",\"created\":1792491170,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":408,\"total_tokens\":1450,\"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\":\"VMvFipALh3uMg0d\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73f1568bb97c1-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:12:53 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3018", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_59a42e5048fe43869752c53939d296fd" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "1a3acc1c808b7b73", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:12:55.220Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_muWWJ3dJhjQZWwre0OGM51I5", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_muWWJ3dJhjQZWwre0OGM51I5" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eVHYr\"}", - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"AnT\"}", - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TdjNY\"}", - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lwnG\"}", - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"J\"}", - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EH6\"}", - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Q3LV70\"}", - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YrqPQ\"}", - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jEfCt\"}", - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8FEKab\"}", - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"C\"}", - "data: {\"id\":\"chatcmpl-Eb17tZKfXmc38yEomgcAKoo4nB2Xj\",\"object\":\"chat.completion.chunk\",\"created\":1792491173,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"jitk9iUW2jweUyL\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73f2a48e097c1-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:12:55 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1441", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_0b0671259b994fb39309e7d537599a12" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:50.422Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-manual.cassette.json deleted file mode 100644 index 4e46e598e..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:12:40.581Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_tp0s1nPH8BcRQ0PCs3jmPllM\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xgkBFkEGP3mtU\"}", - "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-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\":\"sRofcMTb0t\"}", - "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XtYJs2SRW\"}", - "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-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\":\"0soujTOC\"}", - "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wTm7eYfra\"}", - "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6PJMSkpcpdl\"}", - "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-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\":\"9ssag0ZsKm\"}", - "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"xi28xnJJiL9\"}", - "data: {\"id\":\"chatcmpl-Eb17eWCNa6RbzsSM1mbq8BMwnWDp0\",\"object\":\"chat.completion.chunk\",\"created\":1792491158,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"qqZb9FSTlU4MuYc\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73ec808779ed8-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:12:40 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2469", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_fc03c8b837fc4e9ea8eb4d22a0d98e6a" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "749a4127e331fdea", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:12:42.728Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_tp0s1nPH8BcRQ0PCs3jmPllM", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_tp0s1nPH8BcRQ0PCs3jmPllM" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"oC4FS\"}", - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pv4\"}", - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1vaY6\"}", - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"M6uM\"}", - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"U\"}", - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"86H\"}", - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"reY1Nu\"}", - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FnI7K\"}", - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9XN9h\"}", - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8xrNsh\"}", - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"t\"}", - "data: {\"id\":\"chatcmpl-Eb17g9AJJoq8DcUotEixPU5so2XPK\",\"object\":\"chat.completion.chunk\",\"created\":1792491160,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"h07heTeP8GFlF7y\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73ed9d9c29ed8-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:12:42 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1821", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_6e8a548c92154d80a271c491d281cba5" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:48.473Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-auto.cassette.json deleted file mode 100644 index 84eaad06a..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:17:30.828Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_hbRLyJXQCbwABaT8JkqxU3UT\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sXipdyam8y7AH\"}", - "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-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\":\"tuKxl0vnde\"}", - "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XbB3cP1le\"}", - "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-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\":\"onPQCtAm\"}", - "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EG1EWO9cr\"}", - "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ElNhWc9dwej\"}", - "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-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\":\"gkRGhiF8Eh\"}", - "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"fbKBnk5rZkr\"}", - "data: {\"id\":\"chatcmpl-Eb1CKVsQPOj5rm2dq361FfCjEAFLx\",\"object\":\"chat.completion.chunk\",\"created\":1792491448,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"JKC7IaRTimLh80m\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d745dec8e00e6c-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:17:30 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2355", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_785527edebd54757bd38c2d383dd08c2" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "70d11c0d66618968", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:17:33.028Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_hbRLyJXQCbwABaT8JkqxU3UT", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_hbRLyJXQCbwABaT8JkqxU3UT" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jz8O8\"}", - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5q5\"}", - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7AExw\"}", - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Zgx9\"}", - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"J\"}", - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"NyD\"}", - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PRElOz\"}", - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7dEOJ\"}", - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Z4jye\"}", - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kshQcC\"}", - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"N\"}", - "data: {\"id\":\"chatcmpl-Eb1CNH4R9VdwIaof5d7MMexNTocO9\",\"object\":\"chat.completion.chunk\",\"created\":1792491451,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"tzE1LKT4puwVyWO\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d745efec530e6c-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:17:32 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1741", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_818d779af06b44a5bc542273e8e3c1dc" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:05.854Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-manual.cassette.json deleted file mode 100644 index 4a8193491..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-15-latest-ai7-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:17:17.897Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_vos6htgeYnbxPjJb2V83vkNg\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TctEXeabrM8ej\"}", - "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-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\":\"8zgk4M5Fmt\"}", - "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FsEGuJPnd\"}", - "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-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\":\"iUal197b\"}", - "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"L98iZicRR\"}", - "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gMrytTWvFc5\"}", - "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-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\":\"NZBty39Wgg\"}", - "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"wrcmO1Rn0Iu\"}", - "data: {\"id\":\"chatcmpl-Eb1C6B17ELTVh4K0ya41hWYUiDHCg\",\"object\":\"chat.completion.chunk\",\"created\":1792491434,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":536,\"total_tokens\":1578,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"completion_tokens_details\":{\"reasoning_tokens\":512,\"audio_tokens\":0,\"accepted_prediction_tokens\":0,\"rejected_prediction_tokens\":0}},\"obfuscation\":\"okMs4ivv8GYtHmP\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d745851f376fdc-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:17:17 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3638", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_d36b992da0d047bdb5c81cb232e789f5" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "5865068e42732297", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:17:20.451Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_vos6htgeYnbxPjJb2V83vkNg", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_vos6htgeYnbxPjJb2V83vkNg" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"D3etl\"}", - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"r4u\"}", - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gSwYh\"}", - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"51P6\"}", - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"w\"}", - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"B37\"}", - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gqyp9l\"}", - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1xkKX\"}", - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"inp1p\"}", - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rfc12Q\"}", - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"I\"}", - "data: {\"id\":\"chatcmpl-Eb1CAGfGfUjStSB5JADXjPNlAz695\",\"object\":\"chat.completion.chunk\",\"created\":1792491438,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"PkNgICQplBUoOrz\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d7459f384f6fdc-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:17:20 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2022", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_5bb08531aee5455f899afd70180e0281" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:03.619Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-auto.cassette.json deleted file mode 100644 index 4d83edd92..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:08:30.707Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_73X26MC9vqhB9FCNMlaLkqjM\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5T1fQW8T2pN4A\"}", - "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-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\":\"TVvf2EdycH\"}", - "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WzJcg0hsO\"}", - "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-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\":\"FXAXgLbS\"}", - "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"akZXVZUwN\"}", - "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hqK0ubxuTGj\"}", - "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-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\":\"nY4bkzm68q\"}", - "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"TXXl65Wa59E\"}", - "data: {\"id\":\"chatcmpl-Eb13bi35A73DoTmVjxAYUurd4G4Wx\",\"object\":\"chat.completion.chunk\",\"created\":1792490907,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"0WCi88vrqlpzRyL\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d738ab5a59aea3-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:08:30 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3010", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_87b7e7ab9d8649a0882d2c19704bcb4d" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "3ed8f5def82c2711", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:08:33.530Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_73X26MC9vqhB9FCNMlaLkqjM", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_73X26MC9vqhB9FCNMlaLkqjM" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KYXHP\"}", - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Vdf\"}", - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zYjcp\"}", - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"I49W\"}", - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"e\"}", - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0UI\"}", - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0rote7\"}", - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dYIbF\"}", - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cmsBY\"}", - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zn6u3p\"}", - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"K\"}", - "data: {\"id\":\"chatcmpl-Eb13f95SoV8G8x7JIfLsRyhJlwKWv\",\"object\":\"chat.completion.chunk\",\"created\":1792490911,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"FDyHZnNW411e6o9\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d738c039f6aea3-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:08:33 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2401", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_da8ac88bbc0948ae92e7f1bf6c1513d8" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:54.341Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-manual.cassette.json deleted file mode 100644 index d59ae3763..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:08:16.547Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_scbVS2oAyX7SrQdGRaDNoWf3\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DQJDYeCRoZS8p\"}", - "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-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\":\"GZF0t3IIYc\"}", - "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mkxkBO3C3\"}", - "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-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\":\"RAzTqXTA\"}", - "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WzHnQj6I5\"}", - "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EChkz8VrPhM\"}", - "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-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\":\"TQhzrixYe4\"}", - "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"oc1vEJdGvL6\"}", - "data: {\"id\":\"chatcmpl-Eb13LJFvMuGkpdjEoNs3rOl2FgTmK\",\"object\":\"chat.completion.chunk\",\"created\":1792490891,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":600,\"total_tokens\":1642,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"completion_tokens_details\":{\"reasoning_tokens\":576,\"audio_tokens\":0,\"accepted_prediction_tokens\":0,\"rejected_prediction_tokens\":0}},\"obfuscation\":\"cCVpjenufbDYAVn\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d738475cf10cb6-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:08:16 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "4851", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_ba7ed9f1b569430bb46ad15698b91365" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "cb76030617d60e51", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:08:19.264Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_scbVS2oAyX7SrQdGRaDNoWf3", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_scbVS2oAyX7SrQdGRaDNoWf3" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"qzSa2\"}", - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"NBP\"}", - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"SPnRu\"}", - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ayVy\"}", - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"w\"}", - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KFm\"}", - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PBRath\"}", - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"89Jdk\"}", - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"m2Oyp\"}", - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"48Y7dp\"}", - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"H\"}", - "data: {\"id\":\"chatcmpl-Eb13RVu5zqvBXM2UpdfGbaRXVx1gf\",\"object\":\"chat.completion.chunk\",\"created\":1792490897,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"HElpZwJOoxmEAkn\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73867cd780cb6-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:08:19 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2307", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_2d56ee4f2977471ca9aab5231ebeb3f9" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:52.124Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-auto.cassette.json deleted file mode 100644 index b23e6b261..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:10:49.602Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_CujcwW1ft7CAoVQy3oc1dFgs\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"B5zz8OOCTjY1S\"}", - "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-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\":\"3BCeqZP6mV\"}", - "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mLERB2jH6\"}", - "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-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\":\"W7N2mUdy\"}", - "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i0ctHXANr\"}", - "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rSiKDugOdhp\"}", - "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-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\":\"028ZqbwZfX\"}", - "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"TFBIN6n3PYR\"}", - "data: {\"id\":\"chatcmpl-Eb15rFOK3lMHnCIyjHwIe2j94oAj1\",\"object\":\"chat.completion.chunk\",\"created\":1792491047,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"0ROx5C5Mshb0KPE\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73c14ecc590cc-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:10:49 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2110", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_a838f6854e7b490aa320830ff573c9d9" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "5350bfd34e8105a3", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:10:52.158Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_CujcwW1ft7CAoVQy3oc1dFgs", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_CujcwW1ft7CAoVQy3oc1dFgs" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"65y3x\"}", - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Qq5\"}", - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZlV94\"}", - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Lqia\"}", - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"W\"}", - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uQk\"}", - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zpv2bD\"}", - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Y7y8Z\"}", - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Dl1de\"}", - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8j7Jsp\"}", - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"O\"}", - "data: {\"id\":\"chatcmpl-Eb15uk1nJhDhUA4s33y9BA9nSoZe7\",\"object\":\"chat.completion.chunk\",\"created\":1792491050,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":338,\"total_tokens\":1425,\"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\":\"UJBs5uv1vUwAAHQ\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73c24d8e690cc-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:10:52 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2111", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_e6827b71a853436b9c472341fb4f640c" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:10.058Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-manual.cassette.json deleted file mode 100644 index e606feb74..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-ai7-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:10:36.325Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_esbImy3vmBN4m7P5aPKyVpnZ\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Vw6XEZLewlDKl\"}", - "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-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\":\"DNaoJ67Tjj\"}", - "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ExZM2NkSR\"}", - "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-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\":\"TlJAvse3\"}", - "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Etu0alv6q\"}", - "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"AZDFFd8i4uS\"}", - "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-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\":\"cq0i8qz9MA\"}", - "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"m2xJZd5HoD3\"}", - "data: {\"id\":\"chatcmpl-Eb15eY1abEISq304iA7vYzqTebNXD\",\"object\":\"chat.completion.chunk\",\"created\":1792491034,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"u9BFsgackv7PEef\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73bc34b329722-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:10:36 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1872", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_d206d7f4712f430997740ed9c1cf4c08" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "4e853551ac5903d0", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:10:38.232Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_esbImy3vmBN4m7P5aPKyVpnZ", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_esbImy3vmBN4m7P5aPKyVpnZ" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"p9olw\"}", - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"SDk\"}", - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VxQdA\"}", - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"COrU\"}", - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"f\"}", - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"yNQ\"}", - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FqO7mw\"}", - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"T0BVU\"}", - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OHYcx\"}", - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7OpZTI\"}", - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"B\"}", - "data: {\"id\":\"chatcmpl-Eb15gYn0sO2RWHhiP1KYNUIvXLGQ6\",\"object\":\"chat.completion.chunk\",\"created\":1792491036,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"svW0q8jYRz6x1Rg\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73bd18bc49722-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:10:38 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1445", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_902775bb729f4f03a8d4253d7714ea94" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:07.819Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-auto.cassette.json deleted file mode 100644 index 09af46693..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:08:57.204Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_jABav05m6Lh49u7RkhImjYSy\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Q4CbvtFAoVz2r\"}", - "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-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\":\"ZnxkjOco26\"}", - "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fx1pmjtV3\"}", - "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-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\":\"o0LoAIQm\"}", - "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xCbEvlVae\"}", - "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Wpb1msQouPe\"}", - "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-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\":\"3wSoQ4I2Ba\"}", - "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"GnC3ueVggWv\"}", - "data: {\"id\":\"chatcmpl-Eb1435e5GLvU7V7ylCrYn2uYV04J5\",\"object\":\"chat.completion.chunk\",\"created\":1792490935,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"GrbPwnnjKQIVBpo\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d739564fcfe899-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:08:57 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2098", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_7b1256885cb34d2dbda6fa00d5fd3804" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "2e6267c2dce30b4b", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:08:59.903Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_jABav05m6Lh49u7RkhImjYSy", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_jABav05m6Lh49u7RkhImjYSy" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vaNXP\"}", - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rvK\"}", - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DQary\"}", - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cRlo\"}", - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"T\"}", - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8dh\"}", - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4L0Et6\"}", - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JJdAs\"}", - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1dXPE\"}", - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Zr3Iwq\"}", - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"l\"}", - "data: {\"id\":\"chatcmpl-Eb145Kkz2L4iwPrf1yuAN0DA0epHy\",\"object\":\"chat.completion.chunk\",\"created\":1792490937,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":275,\"total_tokens\":1362,\"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\":\"eth1YGg1e7w7nB9\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73965f810e899-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:08:59 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2333", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_838c74705b7f4845aa7821cf6c81625e" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:58.250Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-manual.cassette.json deleted file mode 100644 index b87863e4d..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:08:45.133Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_kQeW1xF8fgmeZioc5LlwZGWr\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MN9hfnrsExyFa\"}", - "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-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\":\"FQNpAQzHQl\"}", - "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lc0hIZYm3\"}", - "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-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\":\"RqKIKB2b\"}", - "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8axETjVJZ\"}", - "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zZ6NfYPuqmH\"}", - "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-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\":\"5n0dn8y0wF\"}", - "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"DVS6lTWY4WY\"}", - "data: {\"id\":\"chatcmpl-Eb13qgFMdWyWbbiDXk3ZRaxyxrGsy\",\"object\":\"chat.completion.chunk\",\"created\":1792490922,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"oKHDYxH060V1N2T\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d739081e44b121-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:08:45 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2581", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_4210eaf10c404b4f9c64dd69a765a040" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "aed2a20a04798f38", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:08:47.301Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_kQeW1xF8fgmeZioc5LlwZGWr", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_kQeW1xF8fgmeZioc5LlwZGWr" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Rnu16\"}", - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4HK\"}", - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"duVIF\"}", - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WEgS\"}", - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"C\"}", - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sGL\"}", - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"QdhybF\"}", - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1NXmS\"}", - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"v5e3b\"}", - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3wMD7l\"}", - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"z\"}", - "data: {\"id\":\"chatcmpl-Eb13tGTbQUseIU2DgLeMe0gWKhoyP\",\"object\":\"chat.completion.chunk\",\"created\":1792490925,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"1k7k3G12D6wEi14\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d7391adb03b121-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:08:47 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1763", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_c1a4b521572344c1b91d487d80ca2429" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:56.285Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-auto.cassette.json deleted file mode 100644 index 37deabc4a..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:11:17.138Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_lohReHw4XtOerCHcrMH3HwSa\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wnZ3r3v4zQa7Z\"}", - "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-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\":\"DBjHaWkyI3\"}", - "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hKwrIRu86\"}", - "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-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\":\"EBqcfB5m\"}", - "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8b2GlTs5X\"}", - "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ck39zAsvYgS\"}", - "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-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\":\"qWtxajS9cA\"}", - "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"UogJT1L8VwQ\"}", - "data: {\"id\":\"chatcmpl-Eb16ImLsKRpRkdrhZdAtkRVpgTfQn\",\"object\":\"chat.completion.chunk\",\"created\":1792491074,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"d5WWCj5xETBhoYf\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73cc0e9e855e3-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:11:17 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2157", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_aae17bd7ccf84d9cada9b1e0f6083095" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "68fc442f7ad1940f", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:11:18.776Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_lohReHw4XtOerCHcrMH3HwSa", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_lohReHw4XtOerCHcrMH3HwSa" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"egDRK\"}", - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Nzo\"}", - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"N7YJJ\"}", - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6ujD\"}", - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"G\"}", - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"myI\"}", - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i8onRy\"}", - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"50Wk4\"}", - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mNPhI\"}", - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"W5OvrR\"}", - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"B\"}", - "data: {\"id\":\"chatcmpl-Eb16LjuxsMvrFrar344O2AJfhVLPR\",\"object\":\"chat.completion.chunk\",\"created\":1792491077,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"gXCZDh1PnNtkH9E\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73cd05dad55e3-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:11:18 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1284", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_b6c41cb7368e4af8a3c6c328909c3701" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:14.012Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-manual.cassette.json deleted file mode 100644 index 1dc1e0ebb..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-16-latest-ai7-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:11:05.329Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_lT5fESmP3VXujDrVhU0jTpWn\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JS6QLbfNLqRfu\"}", - "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-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\":\"g7ER5TS32f\"}", - "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FrGj4U9m9\"}", - "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-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\":\"G0i5xO14\"}", - "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gKHUnO7Uk\"}", - "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"K0YdpFdQGWm\"}", - "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-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\":\"PVxno9FqRH\"}", - "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"xv2OvDMmbOc\"}", - "data: {\"id\":\"chatcmpl-Eb166LXUQCSopzgARiFRmenjcYpRd\",\"object\":\"chat.completion.chunk\",\"created\":1792491062,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"XNv5acOEOwNlDTG\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73c745cef6711-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:11:05 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2588", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_9752b7a89b5f44619cbf60f353d9b1fd" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "e9732e8ff1f1d5f5", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:11:07.375Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_lT5fESmP3VXujDrVhU0jTpWn", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_lT5fESmP3VXujDrVhU0jTpWn" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"QkBF2\"}", - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eo9\"}", - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dMD6B\"}", - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HTLV\"}", - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"m\"}", - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sQl\"}", - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4QbbDy\"}", - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xYpUi\"}", - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vBtUv\"}", - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"frpkcP\"}", - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"s\"}", - "data: {\"id\":\"chatcmpl-Eb169sI5bhOeF4F3YrjWBwDWTonzm\",\"object\":\"chat.completion.chunk\",\"created\":1792491065,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"b9cDxkfDOhTnzNg\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73c869c156711-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:11:07 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1720", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_3d27ad56483a49769eb1a1fe52fe0da8" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:11.802Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-auto.cassette.json deleted file mode 100644 index 1bca5e4bf..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:09:24.567Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_05rnLKgvxquWMWp01PoQH9QC\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"qLlyf7RH6Lbkz\"}", - "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-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\":\"tk64uzvkvg\"}", - "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cpFXscXZE\"}", - "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-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\":\"Z0VSOScd\"}", - "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Y4kiNcpdM\"}", - "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"J3mxBMduaIg\"}", - "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-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\":\"FJPblkHthi\"}", - "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"MUtJDCUHHJM\"}", - "data: {\"id\":\"chatcmpl-Eb14Ut59ih4j0Ch5NAQCQ5jDHXNZV\",\"object\":\"chat.completion.chunk\",\"created\":1792490962,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"HMb9OeeSNiVK1j7\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d739ffde1dbe3d-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:09:24 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2389", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_4c09d9a03464457d8eb2d57d3f1020dc" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "763d121cf819861f", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:09:26.942Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_05rnLKgvxquWMWp01PoQH9QC", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_05rnLKgvxquWMWp01PoQH9QC" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Wq52t\"}", - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Wvr\"}", - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zKNYx\"}", - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HrMV\"}", - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"t\"}", - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"l8K\"}", - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9rmiCT\"}", - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k8yqu\"}", - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uAp7D\"}", - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZIjoaX\"}", - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"U\"}", - "data: {\"id\":\"chatcmpl-Eb14Wyxp2xy0zgth7HcwZ5eHTLGhz\",\"object\":\"chat.completion.chunk\",\"created\":1792490964,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"ccMMEodguysW1M3\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73a10ed6ebe3d-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:09:26 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2004", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_a9f2c7b1c6ce4ccbaea288fa37250f26" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:58:02.138Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-manual.cassette.json deleted file mode 100644 index c20961f0c..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:09:11.569Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_zj47kW1OmTDg9KT3LzNnBFFZ\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JPNieEQLpGOOa\"}", - "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-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\":\"qcfcpUyvFd\"}", - "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"okRrk8hLu\"}", - "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-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\":\"fn9PVIdT\"}", - "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Ci6B9ZIvF\"}", - "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5QbUYN5mc2K\"}", - "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-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\":\"bRqyP6SXYu\"}", - "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"xMgMd2vQ9bs\"}", - "data: {\"id\":\"chatcmpl-Eb14GkVdbmdKnTEZDrKgcnKVhzHRw\",\"object\":\"chat.completion.chunk\",\"created\":1792490948,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"JOwJdz9fJxRYNXw\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d739a93b254547-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:09:11 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3255", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_c03f2314b59049e89f0c5ead3716f7c7" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "b09994c47237c61a", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:09:13.889Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_zj47kW1OmTDg9KT3LzNnBFFZ", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_zj47kW1OmTDg9KT3LzNnBFFZ" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"U2Qac\"}", - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"adM\"}", - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FiBDS\"}", - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Rc6r\"}", - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"w\"}", - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"x9O\"}", - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xf9jCL\"}", - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"n5ljI\"}", - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"yqcfk\"}", - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gGhewn\"}", - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"H\"}", - "data: {\"id\":\"chatcmpl-Eb14JKY5WIxyFVmmiQF8YtlYbCKlk\",\"object\":\"chat.completion.chunk\",\"created\":1792490951,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"STqgtrMLFEWIDz1\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d739bf8c984547-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:09:13 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1986", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_916eb093a8664a6aaec5ccf24cae6b23" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:57:59.945Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-auto.cassette.json deleted file mode 100644 index d286ce40d..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:11:45.781Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_AjsrstVScciOwtnGzG1bLURZ\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1xx7dntXxxATh\"}", - "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-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\":\"yZ0zdY1xob\"}", - "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EUZ47I75n\"}", - "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-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\":\"efM0C30T\"}", - "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3vL9MR2q4\"}", - "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0FRuwhEnAk6\"}", - "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-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\":\"F5iGxERxBv\"}", - "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"pBYJBBE7IUm\"}", - "data: {\"id\":\"chatcmpl-Eb16kGLi8yUmMacDOgOuIErwpuekw\",\"object\":\"chat.completion.chunk\",\"created\":1792491102,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":408,\"total_tokens\":1450,\"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\":\"GfeepGrcWcMYRXV\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73d6a7f78468e-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:11:45 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3627", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_8167fa423a1c4d25815830ceecdd187e" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "c10008cbbbfbe9ad", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:11:49.000Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_AjsrstVScciOwtnGzG1bLURZ", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_AjsrstVScciOwtnGzG1bLURZ" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OZ5K6\"}", - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZKn\"}", - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"S1zTf\"}", - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"o1WC\"}", - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6\"}", - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Ont\"}", - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"j9sMNn\"}", - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TNUxz\"}", - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YHnol\"}", - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5QKQUL\"}", - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"F\"}", - "data: {\"id\":\"chatcmpl-Eb16oOpGhCfUFDPtp8HPhd0rr89vh\",\"object\":\"chat.completion.chunk\",\"created\":1792491106,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"HVu969gaybLBubf\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73d861bca468e-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:11:48 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2374", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_ad4ebbe9072c4513ba103942f2685448" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:17.191Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-manual.cassette.json deleted file mode 100644 index a55745ba4..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-ai7-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:11:29.907Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_JFr0p7MGmQ19j4n7inLZXR8a\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rC8IwdM9tKFoe\"}", - "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-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\":\"itaWdVXOB0\"}", - "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MAM8403Ra\"}", - "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-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\":\"KXeq6vub\"}", - "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XlSOI9DjF\"}", - "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"q9shWpUvglh\"}", - "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-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\":\"zvTkhWRcL4\"}", - "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"SZBkt3FiLiJ\"}", - "data: {\"id\":\"chatcmpl-Eb16Vk9I8Ke2Dov8r84yGks2Qk9X7\",\"object\":\"chat.completion.chunk\",\"created\":1792491087,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"iobg6ptimpWpwZz\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73d120aab299d-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:11:29 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1968", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_a9ab06a4a51f457bbac3b8081536cd73" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "1a13e8e2362f738d", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:11:31.781Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_JFr0p7MGmQ19j4n7inLZXR8a", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_JFr0p7MGmQ19j4n7inLZXR8a" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0YshI\"}", - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Udc\"}", - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"QbFdo\"}", - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kz9J\"}", - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"e\"}", - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ADB\"}", - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"AckZ2r\"}", - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hhpBm\"}", - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hMmBD\"}", - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pqCSQG\"}", - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"d\"}", - "data: {\"id\":\"chatcmpl-Eb16Ykp8uugVZ8MjJDMgWoQwyrcOo\",\"object\":\"chat.completion.chunk\",\"created\":1792491090,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"jHUhEb29GuMgD7B\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73d2048f5299d-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:11:31 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1546", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_9fae578248f940b593221263ad0b142d" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:15.734Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-auto.cassette.json deleted file mode 100644 index 754cfb68d..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:09:52.206Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_ZLXVzLQC0SzSI7FsZYSKLMnQ\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"631lclTyYKemI\"}", - "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-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\":\"A855RJWli0\"}", - "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jEpIV3ini\"}", - "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-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\":\"yKWn5gET\"}", - "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1KGWQLyDi\"}", - "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"buRpsYxkYrR\"}", - "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-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\":\"p1V02VQSfg\"}", - "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"LuxP9RjexbM\"}", - "data: {\"id\":\"chatcmpl-Eb14vJl8DmDrHcAckH1Fwr26yzB1x\",\"object\":\"chat.completion.chunk\",\"created\":1792490989,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"mbC8uLjqT0OmYLj\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73aa99849bb22-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:09:52 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2698", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_94bca2a7f78241b2831931fdeb62ab6f" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "311c6a2fd44939ec", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:09:52.895Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_ZLXVzLQC0SzSI7FsZYSKLMnQ", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_ZLXVzLQC0SzSI7FsZYSKLMnQ" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VnC8v\"}", - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"52n\"}", - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"mvI4p\"}", - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bq55\"}", - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"V\"}", - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jUn\"}", - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"63CDgY\"}", - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Z1bGg\"}", - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Uc5Ga\"}", - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"g0VpEv\"}", - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"p\"}", - "data: {\"id\":\"chatcmpl-Eb14yS2BVhPuiIYi2UScplrsjHpvP\",\"object\":\"chat.completion.chunk\",\"created\":1792490992,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":12,\"total_tokens\":1099,\"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\":\"TS\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73abd999fbb22-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:09:52 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "280", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_a35833937a21462c80c32bb2b8fbec8a" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:58:05.817Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-manual.cassette.json deleted file mode 100644 index 7f5ae75de..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:09:39.019Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_gkptEKyJ8ZngBCtQEFPv5BQN\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DYQh6pqPSia94\"}", - "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-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\":\"BlfxWZULiD\"}", - "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EH9cwKpp5\"}", - "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-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\":\"EjY3AYk2\"}", - "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i6e3JhT4R\"}", - "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LID0DcPchFP\"}", - "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-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\":\"9eD7CxvEnK\"}", - "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"p5UKkmVLRjx\"}", - "data: {\"id\":\"chatcmpl-Eb14iq31xepFBeYYGELPPpOsmmYUY\",\"object\":\"chat.completion.chunk\",\"created\":1792490976,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"0m9FC7l0AJu9I52\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73a5a5b601afc-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:09:38 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2340", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_db21f254ca0c431aad116674d5d33c5b" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "ad1633ea607ec71a", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:09:40.828Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_gkptEKyJ8ZngBCtQEFPv5BQN", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_gkptEKyJ8ZngBCtQEFPv5BQN" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1Wi3C\"}", - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"F7R\"}", - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0QQS2\"}", - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PbAl\"}", - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k\"}", - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1Hk\"}", - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZYEeXH\"}", - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5GSac\"}", - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HRC97\"}", - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cNsDLf\"}", - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"P\"}", - "data: {\"id\":\"chatcmpl-Eb14lsT7q0LTNUR45mpibxCsLYFm0\",\"object\":\"chat.completion.chunk\",\"created\":1792490979,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"rt9rqyfnMrPs7T0\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73a6b3c721afc-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:09:40 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1451", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_951c8acac8b64684a1083509ef217389" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:58:03.857Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-auto.cassette.json deleted file mode 100644 index 52cf64ae2..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:12:16.459Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_kFKeDv4lIYCw8RR74P4ypMWa\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"SsLQh4hbuGqTz\"}", - "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-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\":\"9DrX7nJw3C\"}", - "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MOjN8kEaP\"}", - "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-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\":\"mTSc1OU8\"}", - "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8FJzhhcmj\"}", - "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Ua1DSLfA2O3\"}", - "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-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\":\"aAMR0n8U2k\"}", - "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"2SRIjQ5YUc3\"}", - "data: {\"id\":\"chatcmpl-Eb17Et4JWrlp2aGXuXV8m0Dz2weKt\",\"object\":\"chat.completion.chunk\",\"created\":1792491132,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"qSN96trdObwVrxF\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73e299cd87104-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:12:16 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3761", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_a95cb34d3887485b99841653d390f4ba" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "e59ad52e00aa8bdb", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:12:18.748Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_kFKeDv4lIYCw8RR74P4ypMWa", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_kFKeDv4lIYCw8RR74P4ypMWa" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bO4qQ\"}", - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RH8\"}", - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HRPMC\"}", - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ilCE\"}", - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"6\"}", - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2Qg\"}", - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9ktwFd\"}", - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hewTT\"}", - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"d2ulO\"}", - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FM4Tn3\"}", - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"Q\"}", - "data: {\"id\":\"chatcmpl-Eb17ILwxTXZ4XcN3h0Yju4aM6cpCC\",\"object\":\"chat.completion.chunk\",\"created\":1792491136,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"BCnPuWvALxguxfH\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73e431eeb7104-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:12:18 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1838", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_6c149c3f0b8944deb737d3a395698c14" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:21.070Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-manual.cassette.json deleted file mode 100644 index 158295a13..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-17-latest-ai7-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:12:02.602Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_mI4h5t6atpk9C2yVVRj8zvmX\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TbkirGcwrjuXh\"}", - "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-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\":\"CJ0aad7IEN\"}", - "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"a9o01YcH4\"}", - "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-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\":\"mHmPPBzh\"}", - "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Uye2fDY7k\"}", - "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eYkGfp2djBD\"}", - "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-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\":\"zO6kzxSpJj\"}", - "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"c8OCvX6iwsx\"}", - "data: {\"id\":\"chatcmpl-Eb16zO119WsMUJF9gQf39LnBxY2tP\",\"object\":\"chat.completion.chunk\",\"created\":1792491117,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"Mwfe3aqKPY8gljS\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73dc8ee420692-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:12:02 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "5367", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_43a03d16c66c4fe7803da15adc8a2e0b" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "4cc58523f7bd569e", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:12:05.285Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_mI4h5t6atpk9C2yVVRj8zvmX", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_mI4h5t6atpk9C2yVVRj8zvmX" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zyiwf\"}", - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Np3\"}", - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WvFZ7\"}", - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"A7ez\"}", - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k\"}", - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gSr\"}", - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"IJT194\"}", - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JmOH1\"}", - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"E060D\"}", - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Wqdh3j\"}", - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"A\"}", - "data: {\"id\":\"chatcmpl-Eb175psQbyrUNjfPic9MelFulvsg8\",\"object\":\"chat.completion.chunk\",\"created\":1792491123,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"qe9U4vMPCHwnKoO\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d73dec98930692-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:12:05 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2238", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_60777dc44f3a44ffb00ab8367cb91dc4" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:18.851Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-auto.cassette.json deleted file mode 100644 index 739e696df..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:58:33.178Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_B92ELFZUBDMFNiz7o9of9Be5\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Zf9BZExL6vKYE\"}", - "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-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\":\"KQ4RQm6UpF\"}", - "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fccCb7RAu\"}", - "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-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\":\"x28GVZU7\"}", - "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dfLAzIekj\"}", - "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fXQYz03cfcm\"}", - "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-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\":\"YAcmUpNQDc\"}", - "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"XgfrNR79JOs\"}", - "data: {\"id\":\"chatcmpl-Eb0txb3CUBGMplU2czQTaZgXLABru\",\"object\":\"chat.completion.chunk\",\"created\":1792490309,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":281,\"total_tokens\":1323,\"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\":\"hgKjYW444ANuKUV\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72a0f48ac77ce-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:58:33 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3685", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_fc1c5626ef42417a9e1e2f8e6ee83c31" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "3166ad067546fc91", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:58:38.064Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_B92ELFZUBDMFNiz7o9of9Be5", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_B92ELFZUBDMFNiz7o9of9Be5" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EfQV1\"}", - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ttz\"}", - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MeJFg\"}", - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"T54j\"}", - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4\"}", - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wnA\"}", - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"juAzJ3\"}", - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"BI1m0\"}", - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"IShII\"}", - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"qhXje8\"}", - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"8\"}", - "data: {\"id\":\"chatcmpl-Eb0u1BkKkVpBlcmUzVFJ9dwRdR7D9\",\"object\":\"chat.completion.chunk\",\"created\":1792490313,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":338,\"total_tokens\":1425,\"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\":\"Bsa3DSPwgKF18qc\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72a298b7e77ce-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:58:37 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "4293", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_d855d615f5f94f88918f502dc4742ca8" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:58:38.197Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-manual.cassette.json deleted file mode 100644 index 314b85f27..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:58:18.644Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_HHjjGv2LdPcgB7EVXaFgTARg\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WRsxm6Ytwi5DB\"}", - "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-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\":\"xQCJqJ0KaM\"}", - "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"P1bLmKzSj\"}", - "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-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\":\"YMfmSVmT\"}", - "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lr28Eh3C8\"}", - "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"m3J92MXyhgO\"}", - "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-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\":\"6hA6DxbAfd\"}", - "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"G5PH4p9liMM\"}", - "data: {\"id\":\"chatcmpl-Eb0thHZtvTbCoNI12EdixcrG6tPYP\",\"object\":\"chat.completion.chunk\",\"created\":1792490293,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":408,\"total_tokens\":1450,\"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\":\"ELUegqYM4hp64t1\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d729a94b2eef92-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:58:18 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "5219", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_9fabd6096e6c47fabf2ab837d020e440" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "4445ee4074946e89", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:58:22.944Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_HHjjGv2LdPcgB7EVXaFgTARg", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_HHjjGv2LdPcgB7EVXaFgTARg" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DJSm6\"}", - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"a5E\"}", - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ISMb1\"}", - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fkAj\"}", - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1\"}", - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bFm\"}", - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"oGPpEo\"}", - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"p59vQ\"}", - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"qMUNc\"}", - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k14v2V\"}", - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"O\"}", - "data: {\"id\":\"chatcmpl-Eb0tnKU1WeYf4aZ529py7J5Lj5E9W\",\"object\":\"chat.completion.chunk\",\"created\":1792490299,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"vugfCzMGCuRlS2m\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d729cebf28ef92-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:58:22 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3730", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_44a151b3b71142ec94cac60eb89324e1" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:58:23.081Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-auto.cassette.json deleted file mode 100644 index d5f339be8..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:00:45.391Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_5ThZtti5bEpO335tNVLh3ZBe\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LZr2sZVl1Af6O\"}", - "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-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\":\"6POlRsXFmP\"}", - "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8kLNoq7Ve\"}", - "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-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\":\"eF9RrhnZ\"}", - "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"iJHUlg9LF\"}", - "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"15s8KaA7khX\"}", - "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-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\":\"SUkPqz7uzo\"}", - "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"iUajhw7cfP9\"}", - "data: {\"id\":\"chatcmpl-Eb0w5ryBFYhji2IKyqqwaVsHoGWkR\",\"object\":\"chat.completion.chunk\",\"created\":1792490441,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"A8kLCVI47CaMncN\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72d4a7bffdef8-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:00:45 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3749", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_bc42528bacb741d0b29fd4363e37c9fe" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "55c957cb1e2795e6", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:00:47.759Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_5ThZtti5bEpO335tNVLh3ZBe", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_5ThZtti5bEpO335tNVLh3ZBe" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jiFHK\"}", - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"A18\"}", - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1O6OS\"}", - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xOL7\"}", - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"O\"}", - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3Dn\"}", - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"JLDEQU\"}", - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"eFpMS\"}", - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4su7W\"}", - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5dAaqF\"}", - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"a\"}", - "data: {\"id\":\"chatcmpl-Eb0w9Gje9A1e1swBR7u5D7oQiJLZd\",\"object\":\"chat.completion.chunk\",\"created\":1792490445,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"DH1jlrspoGo1y4Z\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72d63e823def8-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:00:47 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2016", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_bb17794dcecb46a891c68c49d2f8f9df" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:47.878Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-manual.cassette.json deleted file mode 100644 index 76e856338..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-ai7-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:00:31.918Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_sdfZISOxvrCHLIK3nj4uAWDn\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"veuc3a88S5P4u\"}", - "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-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\":\"LtM8c0zf7X\"}", - "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pntQ6lLGx\"}", - "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-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\":\"KMW2p7Vb\"}", - "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"To3ZZT1p0\"}", - "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"aK9DS47hsM5\"}", - "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-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\":\"fGoENuMr3g\"}", - "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"MKkfpokVGND\"}", - "data: {\"id\":\"chatcmpl-Eb0vte4pyHTVvFLeK5THYWnHn5K3i\",\"object\":\"chat.completion.chunk\",\"created\":1792490429,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"bgAK3DExweRI4vg\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72cfb99997d58-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:00:31 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2846", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_db7bef2024e0488b90c607ce431d0ad1" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "7dacb235cbcab544", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:00:35.100Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_sdfZISOxvrCHLIK3nj4uAWDn", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_sdfZISOxvrCHLIK3nj4uAWDn" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"IKAL0\"}", - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bBT\"}", - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Bctwm\"}", - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"9OmN\"}", - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"f\"}", - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vDH\"}", - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jsLkII\"}", - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"A7OGa\"}", - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YSyhF\"}", - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"GYeyEw\"}", - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"M\"}", - "data: {\"id\":\"chatcmpl-Eb0vwi99saAdbTWlEX6briChTLP6v\",\"object\":\"chat.completion.chunk\",\"created\":1792490432,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"Xi46tCbEt3I9mhP\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72d0fcbda7d58-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:00:34 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2816", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_cc3cd879a1884cacba4e9a64329ce1b8" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:00:35.239Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-auto.cassette.json deleted file mode 100644 index a53e8b42c..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:59:03.438Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_xNQDpoCwxAHn5JpQnTDFKN7D\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OsI72d23b8dsl\"}", - "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-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\":\"p7ZEGd2Nxt\"}", - "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"R74UXTvZY\"}", - "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-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\":\"HOfRyBTx\"}", - "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"glkLlom1P\"}", - "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3SgBgDFqj8m\"}", - "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-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\":\"HHWZA5W7r7\"}", - "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"GvyWLUjJpIR\"}", - "data: {\"id\":\"chatcmpl-Eb0uR1Ky1fqxzCMv1JTwjqviOy4fd\",\"object\":\"chat.completion.chunk\",\"created\":1792490339,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"YynEPXl8DbdPas2\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72ace2a3b9e98-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:59:03 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3657", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_fc077af23d3d45a3b9f3d67c553d3477" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "68ba75ee7f10582d", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:59:06.375Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_xNQDpoCwxAHn5JpQnTDFKN7D", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_xNQDpoCwxAHn5JpQnTDFKN7D" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HhoUE\"}", - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nqH\"}", - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cLLDv\"}", - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tGcg\"}", - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"s\"}", - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"f5K\"}", - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KR9T1d\"}", - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5GuSh\"}", - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"GGKtH\"}", - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fD75Xc\"}", - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"B\"}", - "data: {\"id\":\"chatcmpl-Eb0uVTtHf261yf5kNxbKFRwoAIItp\",\"object\":\"chat.completion.chunk\",\"created\":1792490343,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":274,\"total_tokens\":1361,\"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\":\"9a0vyyw83brBOaU\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72ae6a8289e98-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:59:06 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2614", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_dcaebf223fa24a949cdcae038402bf8d" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:59:06.494Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-manual.cassette.json deleted file mode 100644 index b5f6b6b89..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:58:49.747Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_6OYjiftKSop9X0JZBh3SMChY\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"rsEgCh1Fpsb9F\"}", - "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-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\":\"dGEXGIjoXm\"}", - "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"AnxSwXi8q\"}", - "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-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\":\"VTKCiC8U\"}", - "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"prPUskntf\"}", - "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hMbRv4fmEQ2\"}", - "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-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\":\"8ZY4kd98P7\"}", - "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"rMcq4iofjV5\"}", - "data: {\"id\":\"chatcmpl-Eb0uDRkqowVc808IdwGB05viF3x3t\",\"object\":\"chat.completion.chunk\",\"created\":1792490325,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":472,\"total_tokens\":1514,\"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\":\"j4R2vB6fVrgmVyk\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72a727a159eb5-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:58:49 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "4569", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_5d1851cf0d4f42978a22780cec8c96a2" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "4d6ab7b6eb37b3cd", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:58:52.724Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_6OYjiftKSop9X0JZBh3SMChY", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_6OYjiftKSop9X0JZBh3SMChY" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"U3FV2\"}", - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Yk3\"}", - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"aQJlG\"}", - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"By88\"}", - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i\"}", - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"KrI\"}", - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"OgLho1\"}", - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YEcoO\"}", - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Irlul\"}", - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0cBwBW\"}", - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"D\"}", - "data: {\"id\":\"chatcmpl-Eb0uIH3cDi4g3thMp3vphuhsknXum\",\"object\":\"chat.completion.chunk\",\"created\":1792490330,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"MsINEI6yT0tHGmI\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72a911b949eb5-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:58:52 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2630", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_e2a03ee70355439ba4b688d71e8c76e9" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:58:52.848Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-auto.cassette.json deleted file mode 100644 index 67eed5719..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:01:11.209Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_lrj5Nqvby8KWXiUtzjpGUVj5\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dXzrxsIZSgwqr\"}", - "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-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\":\"HZiKdgBmcf\"}", - "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"1PAwWW5Kl\"}", - "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-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\":\"AzMcTOHG\"}", - "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pN4iLQ2Dt\"}", - "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zIeqXQsYL42\"}", - "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-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\":\"oYhuxfOmQQ\"}", - "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"U48e9G8TV1W\"}", - "data: {\"id\":\"chatcmpl-Eb0wWc5yYDFGXK4mm3sJk446GaHOx\",\"object\":\"chat.completion.chunk\",\"created\":1792490468,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"eD2Ot0C0xULTjSL\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72df51e3bd6c6-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:01:11 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2250", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_e39430c2f1494f8d8da1c0eeb0d19901" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "ae787b957a109732", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:01:13.154Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_lrj5Nqvby8KWXiUtzjpGUVj5", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_lrj5Nqvby8KWXiUtzjpGUVj5" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TQ0tk\"}", - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"x1r\"}", - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wCe0N\"}", - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"IVJQ\"}", - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"D\"}", - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"BVg\"}", - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PNrmZj\"}", - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"e2QF4\"}", - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ANdWJ\"}", - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"RSY7yZ\"}", - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"9\"}", - "data: {\"id\":\"chatcmpl-Eb0wZ4WpPkwsZuRDvDW33OQ1hIZf5\",\"object\":\"chat.completion.chunk\",\"created\":1792490471,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"MYpTrBpzxB7EnV5\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72e053976d6c6-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:01:13 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1614", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_ee22b7f29169480e8e3f494d80fd7d60" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:01:13.237Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-manual.cassette.json deleted file mode 100644 index 38974b260..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-18-latest-ai7-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:00:59.075Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_gVUqolvEY2uCJGuSogRdM2Br\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"nzuITc8DqPqhF\"}", - "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-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\":\"yvmoSlqMCx\"}", - "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WWzlCdrpC\"}", - "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-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\":\"CXUptTeS\"}", - "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FNhQoiBj3\"}", - "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ICMGGKiwf4P\"}", - "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-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\":\"rc3zxDlZVh\"}", - "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"a44eOXY5SPG\"}", - "data: {\"id\":\"chatcmpl-Eb0wJD8gFEAURcRiqtTJjDicqFb6i\",\"object\":\"chat.completion.chunk\",\"created\":1792490455,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"jlP36LC4Rxvr51h\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72da1bddebb01-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:00:58 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3322", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_2f8cf14bab0948149ebfe92b3ac79a34" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "268b6df74db78fd4", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:01:01.780Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_gVUqolvEY2uCJGuSogRdM2Br", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_gVUqolvEY2uCJGuSogRdM2Br" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wl1Ys\"}", - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vrv\"}", - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Ow86d\"}", - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"yRKa\"}", - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"D\"}", - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"gKh\"}", - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MZSMa8\"}", - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"SZidJ\"}", - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pmRTY\"}", - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hRD5p3\"}", - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"7\"}", - "data: {\"id\":\"chatcmpl-Eb0wNYHP8PsDBv3a1brAqxmKudleh\",\"object\":\"chat.completion.chunk\",\"created\":1792490459,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"eAkdWesEoaihAhr\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72db97933bb01-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:01:01 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2384", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_ae74e3e5b2024b54b20af441679381e0" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:01:01.949Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-auto.cassette.json deleted file mode 100644 index fe1145f80..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:59:29.818Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_sHA0ZF1N8ggjtSHC4gZLeFdY\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"MFkcxRMobvh6F\"}", - "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-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\":\"ynY64PDaTc\"}", - "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"i9vyIaVc6\"}", - "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-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\":\"OcU62bdw\"}", - "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4iahNzPKr\"}", - "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tmjoCzyWOC2\"}", - "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-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\":\"iFOSaOejBu\"}", - "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"TOmpn4lEBhJ\"}", - "data: {\"id\":\"chatcmpl-Eb0utPi5oXJOp8ilIiWSvxVkIKlqj\",\"object\":\"chat.completion.chunk\",\"created\":1792490367,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"HRx8jVyRRCBrWib\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72b7ddc63d139-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:59:29 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1797", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_33daadefa5c041b3bd7ec685a6d5b4df" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "59950cb3e1c739df", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:59:31.692Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_sHA0ZF1N8ggjtSHC4gZLeFdY", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_sHA0ZF1N8ggjtSHC4gZLeFdY" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"s1K6v\"}", - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"K4w\"}", - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tx7fX\"}", - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"om07\"}", - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7\"}", - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"qsF\"}", - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fZsefr\"}", - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k5wgC\"}", - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pl15Q\"}", - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DSncSl\"}", - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"V\"}", - "data: {\"id\":\"chatcmpl-Eb0uw4wNS817Uh88q68w2jbuAIhoz\",\"object\":\"chat.completion.chunk\",\"created\":1792490370,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"GVv1KwGYssvl0wt\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72b8b8b3bd139-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:59:31 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1589", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_78ad9c5a40054556a8df03c6775e3b2c" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:59:31.890Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-manual.cassette.json deleted file mode 100644 index 12f0c416f..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:59:18.191Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_IFUh6njYa64NPUYhaTZVYYa2\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EkjBJTFGVyyaV\"}", - "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-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\":\"K4kWRn2DQZ\"}", - "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"HoPh1MMrs\"}", - "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-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\":\"BSIhYzuD\"}", - "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"NXrEaMbmx\"}", - "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xquKnOMPR5L\"}", - "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-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\":\"yqovgW3eAt\"}", - "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"nmbaJ7g2fFg\"}", - "data: {\"id\":\"chatcmpl-Eb0uf99BVBVofUQSIQXsyIUjWLXG3\",\"object\":\"chat.completion.chunk\",\"created\":1792490353,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"AScx6UciXJDjmgm\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72b251c999e8b-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:59:18 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "4437", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999802", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_739e35a8481641fab4ac633d156ce895" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "beab81f7a9f98a84", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:59:19.856Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_IFUh6njYa64NPUYhaTZVYYa2", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_IFUh6njYa64NPUYhaTZVYYa2" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"sKwTX\"}", - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"UN7\"}", - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TSlxd\"}", - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"aAca\"}", - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"e\"}", - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wi8\"}", - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"8nyT61\"}", - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"BCA0j\"}", - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YD6zX\"}", - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"FXajZu\"}", - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"i\"}", - "data: {\"id\":\"chatcmpl-Eb0ukA6CtHyVowNclTGLnVLfopFso\",\"object\":\"chat.completion.chunk\",\"created\":1792490358,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":82,\"total_tokens\":1169,\"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\":\"p\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72b42dd109e8b-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:59:19 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1348", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_f419844b3f28413596495edc96dd0b02" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:59:20.029Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-auto.cassette.json deleted file mode 100644 index 08b1405f0..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:01:34.587Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_D7yq9HLW6poTZQJIJMWkODSa\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"wakut9liTY0zA\"}", - "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-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\":\"k32X95yHoW\"}", - "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3jVn1lGIj\"}", - "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-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\":\"0zLFTODm\"}", - "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"AvM1Mi6XO\"}", - "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"cadKaNPcFNN\"}", - "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-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\":\"HBEr4whRSs\"}", - "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"V6BrprleCZO\"}", - "data: {\"id\":\"chatcmpl-Eb0wt5oMl0zxe4WGE2nKBGuz8u4co\",\"object\":\"chat.completion.chunk\",\"created\":1792490491,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":280,\"total_tokens\":1322,\"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\":\"8QR7M9UnvAGtAAM\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72e838a529f94-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:01:34 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2807", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_731100964494444fad25911a06fcf14f" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "c9d6d5bdf521c768", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:01:36.762Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_D7yq9HLW6poTZQJIJMWkODSa", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_D7yq9HLW6poTZQJIJMWkODSa" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"b5TFp\"}", - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3Qf\"}", - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"X7oc8\"}", - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3cvy\"}", - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"n\"}", - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7e7\"}", - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zy6Eh5\"}", - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"U4TmD\"}", - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"yN8d6\"}", - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vYAaqi\"}", - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"b\"}", - "data: {\"id\":\"chatcmpl-Eb0ww6j4wS8z15kr8Hbe1VxNaZHFu\",\"object\":\"chat.completion.chunk\",\"created\":1792490494,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"0nRgZl4KBRhH2UE\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72e9759df9f94-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:01:36 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1779", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_485a795b7020444390a7df2b40d4d41f" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:01:36.871Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-manual.cassette.json deleted file mode 100644 index d23513742..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-ai7-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:01:21.869Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_4dS6X4hDlMFjzMyFSzs9wkqO\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"5BOHZWfcA4vDE\"}", - "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-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\":\"4aphV34ifQ\"}", - "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"pShGIfBCX\"}", - "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-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\":\"78ploexT\"}", - "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"PIxRM7ekA\"}", - "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"7b6VeTZQAdl\"}", - "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-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\":\"Vv1BXFloaA\"}", - "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"J6kIwyBUbYn\"}", - "data: {\"id\":\"chatcmpl-Eb0whwHxdR8TCLhU2VucVzT3fUgqF\",\"object\":\"chat.completion.chunk\",\"created\":1792490479,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"Yd0YEkmW7wDkeww\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72e369a876f02-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:01:21 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2427", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_2d926e759f044bffb6b719b1e8bc606b" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "e3b6da80f41e42f4", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:01:24.318Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_4dS6X4hDlMFjzMyFSzs9wkqO", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_4dS6X4hDlMFjzMyFSzs9wkqO" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"a3TF3\"}", - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Eh1\"}", - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Pgq46\"}", - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Bksl\"}", - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"m\"}", - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"l5U\"}", - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"3ygjNu\"}", - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"U1rqE\"}", - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4Wnoi\"}", - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zUi7Mo\"}", - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"k\"}", - "data: {\"id\":\"chatcmpl-Eb0wkJlAPNte65EW2QjYXuOoqyNmj\",\"object\":\"chat.completion.chunk\",\"created\":1792490482,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":210,\"total_tokens\":1297,\"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\":\"ZX95IcgMBi2vEN9\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72e47ea0c6f02-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:01:24 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2113", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999790", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_7a48c3c202f24a0195ced2e4de317df3" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:01:24.505Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-auto.cassette.json deleted file mode 100644 index 85132c76f..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:59:55.268Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_85JS44Bbc6rjWTaZNzg37YXt\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"fuzjgkEsYNIKJ\"}", - "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-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\":\"L1svs1Wuvf\"}", - "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"hgaoqyTKe\"}", - "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-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\":\"bkPTeFQK\"}", - "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"DOPQlNzaT\"}", - "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"58aWp1aLHMv\"}", - "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-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\":\"2WLQIA8kVd\"}", - "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"jWsfGT11iHD\"}", - "data: {\"id\":\"chatcmpl-Eb0vHXZORAhVDu5RWbIDBGpoMxuPM\",\"object\":\"chat.completion.chunk\",\"created\":1792490391,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":344,\"total_tokens\":1386,\"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\":\"PUXUM7bxVWsT4eZ\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72c10bc4f9a38-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:59:55 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "3822", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_433053277142468bb88ff5e25189940e" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "7f4dc829bbd90154", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:59:56.987Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_85JS44Bbc6rjWTaZNzg37YXt", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_85JS44Bbc6rjWTaZNzg37YXt" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"R5ck4\"}", - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Pbz\"}", - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jzSxf\"}", - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"VSBZ\"}", - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2\"}", - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0gV\"}", - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"oI577Q\"}", - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uqdit\"}", - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"TJAIC\"}", - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tPZKzy\"}", - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"Y\"}", - "data: {\"id\":\"chatcmpl-Eb0vLVRqN7xADb9XhjgUcqGp7ryw8\",\"object\":\"chat.completion.chunk\",\"created\":1792490395,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":82,\"total_tokens\":1169,\"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\":\"7\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72c2a991b9a38-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:59:56 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1339", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_b5009b5b607e463b80ba9f0cf909ac1c" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:59:57.125Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-manual.cassette.json deleted file mode 100644 index 96c5904f8..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai6-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:59:42.964Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_v7WaQrLFlbVaAvbi2LyCY01Z\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"O41qHcfRURikH\"}", - "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-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\":\"jfzg3RpkPt\"}", - "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"WZ5keexCZ\"}", - "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-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\":\"gal5CMtm\"}", - "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"vbEC5MCIV\"}", - "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"jj8XV3DN4z0\"}", - "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-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\":\"CYBpD88jyz\"}", - "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"gQ1DCP8ERZP\"}", - "data: {\"id\":\"chatcmpl-Eb0v6w0tfEgzcDRsW2SIaF1IdJQLa\",\"object\":\"chat.completion.chunk\",\"created\":1792490380,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":281,\"total_tokens\":1323,\"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\":\"Z2AyUwc4bCjqEvd\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72bca7a1c7e8f-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:59:42 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2735", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_0017634ea14c4d139b50dce893515714" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "56bbc404048cb24f", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T09:59:43.812Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_v7WaQrLFlbVaAvbi2LyCY01Z", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_v7WaQrLFlbVaAvbi2LyCY01Z" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k5wX7\"}", - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"xMh\"}", - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"iJXnF\"}", - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"NVqA\"}", - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"O\"}", - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Dy9\"}", - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Lzx3QD\"}", - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"N4sld\"}", - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LiyIU\"}", - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"EjIqR0\"}", - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"z\"}", - "data: {\"id\":\"chatcmpl-Eb0v95qGbGY0PZGvXcGGOxtBeLYQ4\",\"object\":\"chat.completion.chunk\",\"created\":1792490383,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":12,\"total_tokens\":1099,\"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\":\"fN\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72bddbaec7e8f-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 09:59:43 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "266", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_9c22de530acf4a4b951c695f9d04c877" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T09:59:43.985Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-auto.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-auto.cassette.json deleted file mode 100644 index e21a7d8a0..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-auto.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:02:01.541Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_pKyBLhpNnk0up8OzqLvokeGn\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"LXN46ZyOs5JRN\"}", - "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-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\":\"XqmaQqkNUi\"}", - "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"L9m3cxh6k\"}", - "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-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\":\"xhFICKFU\"}", - "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"C6kvPZtZl\"}", - "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2xnjy0uHnD5\"}", - "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-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\":\"K1UB5alHdG\"}", - "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"YqN9z43JhO5\"}", - "data: {\"id\":\"chatcmpl-Eb0xKIs5LKkpGYqbXl5iioePmixRf\",\"object\":\"chat.completion.chunk\",\"created\":1792490518,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"NRCaj8PM3ctXMz8\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72f2cf83dff34-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:02:01 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2682", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_0f2e9de7d8f144b2865be460c8341cb7" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "f58bfb7fba7a8fa5", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:02:03.666Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_pKyBLhpNnk0up8OzqLvokeGn", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_pKyBLhpNnk0up8OzqLvokeGn" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"dL0x1\"}", - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YXu\"}", - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"XAvua\"}", - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"r8Cu\"}", - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"s\"}", - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"kBJ\"}", - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"SfzBhA\"}", - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"Fb5s4\"}", - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"4qBHe\"}", - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"x24IJR\"}", - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"n\"}", - "data: {\"id\":\"chatcmpl-Eb0xNG7j2oazeAmEUqANisVnwGTpm\",\"object\":\"chat.completion.chunk\",\"created\":1792490521,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"sl2z5HWbhzrHbiK\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72f4049ecff34-CDG", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:02:03 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1654", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_80d70c81490a4c9684d44b948be1de45" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:02:03.878Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-manual.cassette.json b/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-manual.cassette.json deleted file mode 100644 index 4b3a095af..000000000 --- a/e2e/scenarios/cloudflare-think-instrumentation/__cassettes__/cloudflare-think-v0-19-latest-ai7-manual.cassette.json +++ /dev/null @@ -1,645 +0,0 @@ -{ - "entries": [ - { - "callIndex": 0, - "id": "02bfffc5f7e45fcc", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:01:46.787Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"index\":0,\"id\":\"call_lxSYIpPRyMC659O73xCA1f7P\",\"type\":\"function\",\"function\":{\"name\":\"lookup_weather\",\"arguments\":\"\"}}],\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"zgeyx3HrTZPOY\"}", - "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-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\":\"Elq2OcWWTa\"}", - "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"lipp2Ebfo\"}", - "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-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\":\"gys5mBrD\"}", - "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Vien\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"2xHA4C41y\"}", - "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"na\"}}]},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"tCrBKNP50so\"}", - "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-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\":\"Ozu3YhiPix\"}", - "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"tool_calls\"}],\"usage\":null,\"obfuscation\":\"DnZlDGqqHWa\"}", - "data: {\"id\":\"chatcmpl-Eb0x6FR2tdVgOJIpKqpSclKEMwJTz\",\"object\":\"chat.completion.chunk\",\"created\":1792490504,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1042,\"completion_tokens\":216,\"total_tokens\":1258,\"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\":\"liapAZtlEatVUXw\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72ed2cc40b192-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:01:46 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "2382", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999805", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_93bfa6a57b5a4600ad3f5fa2707686ac" - }, - "status": 200 - } - }, - { - "callIndex": 1, - "id": "e9e0dd47a4155fd1", - "matchKey": "POST api.openai.com/v1/chat/completions", - "recordedAt": "2026-10-20T10:01:49.097Z", - "request": { - "body": { - "kind": "json", - "value": { - "messages": [ - { - "content": "You are a deterministic weather-test agent. You must call lookup_weather exactly once with Vienna before answering. After the tool result, reply with exactly: \"Vienna is sunny and 21°C.\"\n\nYou are running inside a Think agent.\n\nCapabilities available in this turn:\n- You can inspect and edit the agent workspace using the available file tools.\n- Use the tools exposed in this turn when they materially improve accuracy or let you act on the user's request. Treat tool descriptions and schemas as the source of truth.\n- Some tools may call server code, browser/client code, MCP servers, extensions, or delegated agents. Use them according to their descriptions.\n- Do not claim access to capabilities that are not exposed as tools in this turn.", - "role": "developer" - }, - { - "content": "What is the weather in Vienna?", - "role": "user" - }, - { - "content": null, - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"city\":\"Vienna\"}", - "name": "lookup_weather" - }, - "id": "call_lxSYIpPRyMC659O73xCA1f7P", - "type": "function" - } - ] - }, - { - "content": "{\"city\":\"Vienna\",\"condition\":\"sunny\",\"degreesC\":21}", - "role": "tool", - "tool_call_id": "call_lxSYIpPRyMC659O73xCA1f7P" - } - ], - "model": "gpt-5-nano", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "function": { - "description": "Read a workspace file. Text files return line-numbered content. Images and PDFs are passed to capable models as file content. Use offset and limit for large text files. Returns null if the file does not exist.", - "name": "read", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Number of lines to read", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "1-indexed line number to start reading from", - "maximum": 9007199254740991, - "minimum": 1, - "type": "integer" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Write content to a file. Creates the file if it does not exist, overwrites if it does. Parent directories are created automatically.", - "name": "write", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "content": { - "description": "Content to write to the file", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "content"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Make a targeted edit to a file by replacing an exact string match. Provide the old_string to find and new_string to replace it with. The old_string must match exactly (including whitespace and indentation). Use an empty old_string with new_string to create a new file.", - "name": "edit", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "new_string": { - "description": "Replacement text", - "type": "string" - }, - "old_string": { - "description": "Exact text to find and replace. Empty string to create a new file.", - "type": "string" - }, - "path": { - "description": "Absolute path to the file", - "type": "string" - } - }, - "required": ["path", "old_string", "new_string"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "List files and directories in a given path. Returns names, types, and sizes for each entry.", - "name": "list", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "limit": { - "description": "Maximum number of entries to return (default: 200)", - "maximum": 1000, - "minimum": 1, - "type": "integer" - }, - "offset": { - "description": "Number of entries to skip (for pagination)", - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "path": { - "default": "/", - "description": "Absolute path to the directory to list", - "type": "string" - } - }, - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Find files matching a glob pattern. Supports standard glob syntax: * matches any file, ** matches directories recursively, ? matches a single character. Returns matching file paths with types and sizes.", - "name": "find", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "pattern": { - "description": "Glob pattern to match (e.g. \"**/*.ts\", \"src/**/*.test.ts\", \"*.md\")", - "type": "string" - } - }, - "required": ["pattern"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Search file contents using a regular expression or fixed string. Returns matching lines with file paths and line numbers. Searches all files matching the include glob, or all files if not specified.", - "name": "grep", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "caseSensitive": { - "description": "If true, search is case-sensitive (default: false)", - "type": "boolean" - }, - "contextLines": { - "description": "Number of context lines around each match (default: 0)", - "maximum": 10, - "minimum": 0, - "type": "integer" - }, - "fixedString": { - "description": "If true, treat query as a literal string instead of regex", - "type": "boolean" - }, - "include": { - "description": "Glob pattern to filter files (e.g. \"**/*.ts\"). Defaults to \"**/*\"", - "type": "string" - }, - "query": { - "description": "Search pattern (regex or fixed string)", - "type": "string" - } - }, - "required": ["query"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Delete a file or directory. Set recursive to true to remove non-empty directories.", - "name": "delete", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "path": { - "description": "Absolute path to the file or directory", - "type": "string" - }, - "recursive": { - "description": "If true, remove directories and their contents recursively", - "type": "boolean" - } - }, - "required": ["path"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Run a Bash script against the workspace. Use for shell-style workflows that combine multiple file operations. The script runs in a sandboxed virtual filesystem with the workspace mounted at `/` (also the default working directory) — there is no `/workspace` or `/home`; use absolute paths like `/notes.txt`. Changed files are written back to the workspace.", - "name": "bash", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "cwd": { - "description": "Working directory for the script. Defaults to / (the workspace root)", - "type": "string" - }, - "script": { - "description": "Bash script to run", - "type": "string" - } - }, - "required": ["script"], - "type": "object" - } - }, - "type": "function" - }, - { - "function": { - "description": "Get deterministic weather for a city.", - "name": "lookup_weather", - "parameters": { - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "properties": { - "city": { - "type": "string" - } - }, - "required": ["city"], - "type": "object" - } - }, - "type": "function" - } - ] - } - }, - "headers": {}, - "method": "POST", - "url": "https://api.openai.com/v1/chat/completions" - }, - "response": { - "body": { - "chunks": [ - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uH8K2\"}", - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Vien\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"k0U\"}", - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"na\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"uyyto\"}", - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"bJ8B\"}", - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"F\"}", - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"R95\"}", - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"ZmIauS\"}", - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"21\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"V1g8w\"}", - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"YRddJ\"}", - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\"},\"finish_reason\":null}],\"usage\":null,\"obfuscation\":\"0rO5kJ\"}", - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}],\"usage\":null,\"obfuscation\":\"V\"}", - "data: {\"id\":\"chatcmpl-Eb0x9Ms51lwGlTO9Y5hrdQ8OaPRmM\",\"object\":\"chat.completion.chunk\",\"created\":1792490507,\"model\":\"gpt-5-nano-2025-08-07\",\"service_tier\":\"default\",\"system_fingerprint\":null,\"choices\":[],\"usage\":{\"prompt_tokens\":1087,\"completion_tokens\":146,\"total_tokens\":1233,\"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\":\"Sjur7aPJ10OgEWl\"}", - "data: [DONE]" - ], - "kind": "sse" - }, - "headers": { - "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", - "alt-svc": "h3=\":443\"; ma=86400", - "cf-cache-status": "DYNAMIC", - "cf-ray": "a4d72ee73d7eb192-AMS", - "content-type": "text/event-stream; charset=utf-8", - "date": "Tue, 20 Oct 2026 10:01:48 GMT", - "openai-organization": "braintrust-data", - "openai-processing-ms": "1400", - "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", - "openai-version": "2020-10-01", - "server": "cloudflare", - "set-cookie": "[REDACTED]", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "x-content-type-options": "nosniff", - "x-openai-proxy-wasm": "v0.1", - "x-ratelimit-limit-requests": "30000", - "x-ratelimit-limit-tokens": "180000000", - "x-ratelimit-remaining-requests": "29999", - "x-ratelimit-remaining-tokens": "179999787", - "x-ratelimit-reset-requests": "2ms", - "x-ratelimit-reset-tokens": "0s", - "x-request-id": "req_ea8607cc68614ff599d4df16f246d4b9" - }, - "status": 200 - } - } - ], - "meta": { - "createdAt": "2026-10-20T10:01:49.697Z" - } -} diff --git a/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts b/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts index 780d32d38..8452a8557 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts +++ b/e2e/scenarios/cloudflare-think-instrumentation/assertions.ts @@ -22,12 +22,16 @@ type ScenarioRunner = (harness: { export function defineCloudflareThinkAssertions(options: { name: string; runScenario: ScenarioRunner; - snapshotName?: string; + snapshotName: string; testFileUrl: string; timeoutMs: number; usesV7Telemetry: boolean; }): void { const timeoutMs = effectiveScenarioTimeoutMs(options.timeoutMs); + const snapshotPath = resolveFileSnapshotPath( + options.testFileUrl, + `${options.snapshotName}.span-tree.json`, + ); describe(options.name, () => { let events: CapturedLogEvent[] = []; @@ -129,13 +133,6 @@ export function defineCloudflareThinkAssertions(options: { }, ); - if (!options.snapshotName) { - return; - } - const snapshotPath = resolveFileSnapshotPath( - options.testFileUrl, - `${options.snapshotName}.span-tree.json`, - ); test("matches the span tree snapshot", { timeout: timeoutMs }, async () => { expect(setupError).toBeUndefined(); const names = new Set(["Think.runTurn", "doStream", "lookup_weather"]); diff --git a/e2e/scenarios/cloudflare-think-instrumentation/package.json b/e2e/scenarios/cloudflare-think-instrumentation/package.json index 47f778000..d97a52230 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/package.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/package.json @@ -11,72 +11,6 @@ "targetManifest": "versions/ai6/package.json", "targetDependency": "cloudflare-think-v0-13-latest" }, - "cloudflare-think-v0-14-latest-ai6": { - "package": "@cloudflare/think", - "range": ">=0.14.0 <0.15.0", - "targetManifest": "versions/ai6/package.json", - "targetDependency": "cloudflare-think-v0-14-latest" - }, - "cloudflare-think-v0-15-latest-ai6": { - "package": "@cloudflare/think", - "range": ">=0.15.0 <0.16.0", - "targetManifest": "versions/ai6/package.json", - "targetDependency": "cloudflare-think-v0-15-latest" - }, - "cloudflare-think-v0-16-latest-ai6": { - "package": "@cloudflare/think", - "range": ">=0.16.0 <0.17.0", - "targetManifest": "versions/ai6/package.json", - "targetDependency": "cloudflare-think-v0-16-latest" - }, - "cloudflare-think-v0-17-latest-ai6": { - "package": "@cloudflare/think", - "range": ">=0.17.0 <0.18.0", - "targetManifest": "versions/ai6/package.json", - "targetDependency": "cloudflare-think-v0-17-latest" - }, - "cloudflare-think-v0-18-latest-ai6": { - "package": "@cloudflare/think", - "range": ">=0.18.0 <0.19.0", - "targetManifest": "versions/ai6/package.json", - "targetDependency": "cloudflare-think-v0-18-latest" - }, - "cloudflare-think-v0-19-latest-ai6": { - "package": "@cloudflare/think", - "range": ">=0.19.0 <0.20.0", - "targetManifest": "versions/ai6/package.json", - "targetDependency": "cloudflare-think-v0-19-latest" - }, - "cloudflare-think-v0-15-latest-ai7": { - "package": "@cloudflare/think", - "range": ">=0.15.0 <0.16.0", - "targetManifest": "versions/ai7/package.json", - "targetDependency": "cloudflare-think-v0-15-latest" - }, - "cloudflare-think-v0-16-latest-ai7": { - "package": "@cloudflare/think", - "range": ">=0.16.0 <0.17.0", - "targetManifest": "versions/ai7/package.json", - "targetDependency": "cloudflare-think-v0-16-latest" - }, - "cloudflare-think-v0-17-latest-ai7": { - "package": "@cloudflare/think", - "range": ">=0.17.0 <0.18.0", - "targetManifest": "versions/ai7/package.json", - "targetDependency": "cloudflare-think-v0-17-latest" - }, - "cloudflare-think-v0-18-latest-ai7": { - "package": "@cloudflare/think", - "range": ">=0.18.0 <0.19.0", - "targetManifest": "versions/ai7/package.json", - "targetDependency": "cloudflare-think-v0-18-latest" - }, - "cloudflare-think-v0-19-latest-ai7": { - "package": "@cloudflare/think", - "range": ">=0.19.0 <0.20.0", - "targetManifest": "versions/ai7/package.json", - "targetDependency": "cloudflare-think-v0-19-latest" - }, "cloudflare-think-v0-20-latest-ai7": { "package": "@cloudflare/think", "range": ">=0.20.0 <0.21.0", diff --git a/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts b/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts index 96d600b16..f088dcd3f 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts +++ b/e2e/scenarios/cloudflare-think-instrumentation/scenario.test.ts @@ -12,7 +12,10 @@ const originalScenarioDir = resolveScenarioDir(import.meta.url); const TIMEOUT_MS = 300_000; const variants = []; -for (const aiMajor of [6, 7]) { +for (const [aiMajor, minor] of [ + [6, 13], + [7, 20], +] as const) { const sourceDir = path.resolve( originalScenarioDir, `../../.bt-tmp/generated-scenarios/cloudflare-think-ai${aiMajor}`, @@ -27,38 +30,26 @@ for (const aiMajor of [6, 7]) { sourceDir, { recursive: true }, ); - const minors = - aiMajor === 6 ? [13, 14, 15, 16, 17, 18, 19] : [15, 16, 17, 18, 19, 20]; - for (const minor of minors) { - for (const lane of [ - "pinned", - "latest", - ...(minor === 20 ? ["0.20.1"] : []), - ]) { - // Each concurrently running variant writes its own .dev.vars and Worker - // storage. Share the dependency cache, but not the application directory. - const scenarioDir = await prepareScenarioDir({ scenarioDir: sourceDir }); - const dependencyName = `cloudflare-think-v0-${minor}${ - lane === "latest" ? "-latest" : lane === "0.20.1" ? "-1" : "" - }`; - variants.push({ - aiMajor, - agentsPackageName: - minor === 13 - ? "agents-v0-17" - : minor === 14 || (minor === 15 && lane === "pinned") - ? "agents-v0-18" - : minor <= 17 - ? "agents-v0-22" - : "agents", - dependencyName, - snapshot: minor === 13 || minor === 20, - label: `0.${minor} ${lane} / AI SDK ${aiMajor}`, - scenarioDir, - variantKey: `${dependencyName}-ai${aiMajor}`, - version: await readInstalledPackageVersion(scenarioDir, dependencyName), - }); - } + for (const lane of [ + "pinned", + "latest", + ...(minor === 20 ? ["0.20.1"] : []), + ]) { + // Each concurrently running variant writes its own .dev.vars and Worker + // storage. Share the dependency cache, but not the application directory. + const scenarioDir = await prepareScenarioDir({ scenarioDir: sourceDir }); + const dependencyName = `cloudflare-think-v0-${minor}${ + lane === "latest" ? "-latest" : lane === "0.20.1" ? "-1" : "" + }`; + variants.push({ + aiMajor, + agentsPackageName: minor === 13 ? "agents-v0-17" : "agents", + dependencyName, + label: `0.${minor} ${lane} / AI SDK ${aiMajor}`, + scenarioDir, + variantKey: `${dependencyName}-ai${aiMajor}`, + version: await readInstalledPackageVersion(scenarioDir, dependencyName), + }); } } @@ -90,9 +81,7 @@ describeVariants("Cloudflare Think variants", () => { timeoutMs: TIMEOUT_MS, }); }, - snapshotName: variant.snapshot - ? `${variant.variantKey}-${mode}` - : undefined, + snapshotName: `${variant.variantKey}-${mode}`, testFileUrl: import.meta.url, timeoutMs: TIMEOUT_MS, }); diff --git a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/package.json b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/package.json index 90111456b..96df71715 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/package.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/package.json @@ -14,21 +14,7 @@ "zod": "4.3.6", "cloudflare-think-v0-13": "npm:@cloudflare/think@0.13.0", "cloudflare-think-v0-13-latest": "npm:@cloudflare/think@0.13.0", - "cloudflare-think-v0-14": "npm:@cloudflare/think@0.14.0", - "cloudflare-think-v0-14-latest": "npm:@cloudflare/think@0.14.0", - "cloudflare-think-v0-15": "npm:@cloudflare/think@0.15.0", - "cloudflare-think-v0-15-latest": "npm:@cloudflare/think@0.15.1", - "cloudflare-think-v0-16": "npm:@cloudflare/think@0.16.0", - "cloudflare-think-v0-16-latest": "npm:@cloudflare/think@0.16.0", - "cloudflare-think-v0-17": "npm:@cloudflare/think@0.17.0", - "cloudflare-think-v0-17-latest": "npm:@cloudflare/think@0.17.0", - "cloudflare-think-v0-18": "npm:@cloudflare/think@0.18.0", - "cloudflare-think-v0-18-latest": "npm:@cloudflare/think@0.18.0", - "cloudflare-think-v0-19": "npm:@cloudflare/think@0.19.0", - "cloudflare-think-v0-19-latest": "npm:@cloudflare/think@0.19.0", - "agents-v0-17": "npm:agents@0.17.4", - "agents-v0-18": "npm:agents@0.18.0", - "agents-v0-22": "npm:agents@0.22.0" + "agents-v0-17": "npm:agents@0.17.4" }, "pnpm": { "overrides": { diff --git a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/pnpm-lock.yaml b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/pnpm-lock.yaml index 32bb627e0..b5dea9f9a 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/pnpm-lock.yaml +++ b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai6/pnpm-lock.yaml @@ -42,12 +42,6 @@ importers: agents-v0-17: specifier: npm:agents@0.17.4 version: agents@0.17.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/workers-types@5.20261019.1)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - agents-v0-18: - specifier: npm:agents@0.18.0 - version: agents@0.18.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/workers-types@5.20261019.1)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - agents-v0-22: - specifier: npm:agents@0.22.0 - version: agents@0.22.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) ai: specifier: 6.0.202 version: 6.0.202(zod@4.3.6) @@ -60,42 +54,6 @@ importers: cloudflare-think-v0-13-latest: specifier: npm:@cloudflare/think@0.13.0 version: '@cloudflare/think@0.13.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' - cloudflare-think-v0-14: - specifier: npm:@cloudflare/think@0.14.0 - version: '@cloudflare/think@0.14.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' - cloudflare-think-v0-14-latest: - specifier: npm:@cloudflare/think@0.14.0 - version: '@cloudflare/think@0.14.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' - cloudflare-think-v0-15: - specifier: npm:@cloudflare/think@0.15.0 - version: '@cloudflare/think@0.15.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' - cloudflare-think-v0-15-latest: - specifier: npm:@cloudflare/think@0.15.1 - version: '@cloudflare/think@0.15.1(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' - cloudflare-think-v0-16: - specifier: npm:@cloudflare/think@0.16.0 - version: '@cloudflare/think@0.16.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-16-latest: - specifier: npm:@cloudflare/think@0.16.0 - version: '@cloudflare/think@0.16.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-17: - specifier: npm:@cloudflare/think@0.17.0 - version: '@cloudflare/think@0.17.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-17-latest: - specifier: npm:@cloudflare/think@0.17.0 - version: '@cloudflare/think@0.17.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-18: - specifier: npm:@cloudflare/think@0.18.0 - version: '@cloudflare/think@0.18.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-18-latest: - specifier: npm:@cloudflare/think@0.18.0 - version: '@cloudflare/think@0.18.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-19: - specifier: npm:@cloudflare/think@0.19.0 - version: '@cloudflare/think@0.19.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-19-latest: - specifier: npm:@cloudflare/think@0.19.0 - version: '@cloudflare/think@0.19.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' dc-browser: specifier: 1.0.4 version: 1.0.4 @@ -117,12 +75,6 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/anthropic@4.0.84': - resolution: {integrity: sha512-jcqib3OpVtcMmJDWYpQqkjAusaLyqfORyM4bDc3UwLgP/usfiTONfj98HeQCLwMJ2uxrmSWiXFga2Rw/k50usw==} - engines: {node: '>=22'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/gateway@3.0.128': resolution: {integrity: sha512-t9Dyqk5thSmIzsNvVTQtZZiO3xqKGkk1hX3+GNpYmro+GuEdW+E6mKFHihb9Y1vCEt3rEyd4pbGUcin4D57FfQ==} engines: {node: '>=18'} @@ -135,12 +87,6 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/openai@4.0.98': - resolution: {integrity: sha512-RvrbLblENKj//cQWlzsbmVKvvV8ZUq8FFB8/68ODWnu5sS3T+lUmRoKOM7NjR2UIX0/7YDrtauJr9fxQ0cwkug==} - engines: {node: '>=22'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider-utils@4.0.28': resolution: {integrity: sha512-nCtGJY43Kqwoyk0rYLj80a3eyXxcaWwyu+lYZDHgY+U6JbYYyvRdRTSy+XCDIB91rFH0Ul0eMDHmDr+YMYtrSw==} engines: {node: '>=18'} @@ -159,12 +105,6 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider-utils@5.0.64': - resolution: {integrity: sha512-BDU8rDR6mBR+na5U/Dj4B33LX980x200lqhBGRIOxxx1NFunoixuvvweqIB+sCsCoFC8cGCsa82Ce2fKoAPOqw==} - engines: {node: '>=22'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider@3.0.10': resolution: {integrity: sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw==} engines: {node: '>=18'} @@ -177,10 +117,6 @@ packages: resolution: {integrity: sha512-5lWq7zSfRaU5ylDESn3sDQjgGl2AI1vjZKO/6JY3aFW70ct4zcP1kN+ZUYOuTXr28fVsYbyu2YFhddLdIgQFZQ==} engines: {node: '>=18'} - '@ai-sdk/provider@4.0.31': - resolution: {integrity: sha512-3wJnwVTFg8SwOyoZCv+ov7Re2GB+7IQnU5a5MYJACrtiWDDUHgqTBeeesq2MB2ddgojzL8hgWleltwpAgtUqfg==} - engines: {node: '>=22'} - '@babel/code-frame@8.0.6': resolution: {integrity: sha512-uMHhvmDmwFiLuiozaoRYTZHqMFuu3fem/X9JY78lohAuLoh8LSGGC8JqUzo2cVuBsBxkjMZNk56CE7ock8Xxkw==} engines: {node: ^22.18.0 || >=24.11.0} @@ -364,137 +300,6 @@ packages: vite: optional: true - '@cloudflare/think@0.14.0': - resolution: {integrity: sha512-YQT1FJx6LwFrtsy3yr3Wd9QWVRIuijAxtFzA7JAOqJOO3ZBSnBJPlJ6S8OftojPU4GcIxEkyFNUyCgHD3jEc3g==} - hasBin: true - peerDependencies: - '@ai-sdk/react': ^3.0.204 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.18.0 <1.0.0' - ai: ^6.0.182 - react: ^19.0.0 - vite: '>=6 <9' - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - vite: - optional: true - - '@cloudflare/think@0.15.0': - resolution: {integrity: sha512-vI7YhGRrxbsnMEA6gVWD7aaWxa9dZOJBFuc+d9DZVLD7jfasO1egJ6LbS7VS6kfjCBETIzudi+wlmS3wYISEYg==} - hasBin: true - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.18.0 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - vite: '>=6 <9' - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - vite: - optional: true - - '@cloudflare/think@0.15.1': - resolution: {integrity: sha512-BAMVRoBArhszewE0ONcq6sNxfB0QsXIZkhdZYl+6hXdUC/tHShRK1ZDaGhHuWhDBBGYsPY07ploFy4WOmCLkwQ==} - hasBin: true - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.18.0 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - vite: '>=6 <9' - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - vite: - optional: true - - '@cloudflare/think@0.16.0': - resolution: {integrity: sha512-SVUJR+ENNL/eu7L5fNZCYALd72DRJYSiu7efNyr6hzNwFXYZSZz0Ecz06DoPLfN6k+F5ABO+0CHLVLAfAtr7dA==} - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.20.2 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - - '@cloudflare/think@0.17.0': - resolution: {integrity: sha512-tnfMZSqSz1dhfBx0io/mXMJE2huwJc2kTPAkx55y1bTUQwt9A2uONBmN1FixNsI9DFp1zXJDzcO0juGFKfTyLQ==} - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.20.2 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - - '@cloudflare/think@0.18.0': - resolution: {integrity: sha512-eN3gZvO05UPucAaQ9GfIu5iKhMeRKqd+NzxfNdi3rhbAHhsTC3ckxPnXNlBmr8Pg0zcvaJK69KhWPv4AySeexQ==} - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.23.0 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - - '@cloudflare/think@0.19.0': - resolution: {integrity: sha512-7xYaVeQJA4Xnwuo2R5/zhbUjWftvKzVjdsZnOSYjo+BqJ+hbizemW8fCt1QTTP+TDixgXXiOQNlOmyNJXjTYUw==} - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.24.0 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - '@cloudflare/unenv-preset@2.16.1': resolution: {integrity: sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==} peerDependencies: @@ -1401,9 +1206,6 @@ packages: resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} engines: {node: '>= 20'} - '@workflow/serde@4.1.0': - resolution: {integrity: sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==} - '@workflow/serde@4.1.0-beta.2': resolution: {integrity: sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww==} @@ -1452,77 +1254,6 @@ packages: vite: optional: true - agents@0.18.0: - resolution: {integrity: sha512-ozQCDZrJerDMW/2/X3N+y6yzB4PAfiMtPN4jhK5fD+CFdYfc35k0mqNf/GTWzMA6Pc7WekOB/nFaAlIMrH9WvA==} - hasBin: true - peerDependencies: - '@ai-sdk/react': ^3.0.204 - '@tanstack/ai': '>=0.10.2 <1.0.0' - '@x402/core': ^2.0.0 - '@x402/evm': ^2.0.0 - ai: ^6.0.0 - chat: ^4.29.0 - just-bash: ^3.0.0 - react: ^19.0.0 - vite: '>=6.0.0 <9.0.0' - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@tanstack/ai': - optional: true - '@x402/core': - optional: true - '@x402/evm': - optional: true - ai: - optional: true - chat: - optional: true - just-bash: - optional: true - vite: - optional: true - - agents@0.22.0: - resolution: {integrity: sha512-dIy/BRdO5GSqdOIp0pmkcLmHCCxIKb4RBByXFXmXG6Nc6WBSNYRXoLLDvWj2fJAfi4l5/OndJjZuBAP0vW0DZQ==} - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@cloudflare/codemode': '>=0.5.0' - '@modelcontextprotocol/client': 2.0.0 - '@modelcontextprotocol/sdk': 1.31.0 - '@modelcontextprotocol/server': 2.0.0 - '@tanstack/ai': '>=0.10.2 <1.0.0' - '@x402/core': ^2.0.0 - '@x402/evm': ^2.0.0 - ai: ^6.0.0 || ^7.0.0 - chat: ^4.29.0 - just-bash: ^3.0.0 - react: ^19.0.0 - vite: '>=6.0.0 <9.0.0' - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@cloudflare/codemode': - optional: true - '@tanstack/ai': - optional: true - '@x402/core': - optional: true - '@x402/evm': - optional: true - ai: - optional: true - chat: - optional: true - just-bash: - optional: true - react: - optional: true - vite: - optional: true - agents@0.28.0: resolution: {integrity: sha512-5nYoykTqL6HWLwRyPP9XL4triRg+kkc6W1Ovt58lMz3oLbChRst6GWQVU3LvLgve8YIbo1SvQp0IR4TOrxAD6g==} hasBin: true @@ -2812,22 +2543,6 @@ packages: '@ai-sdk/openai': optional: true - workers-ai-provider@4.0.0: - resolution: {integrity: sha512-FkhwMP1EP/MKXR8Jv1o7wLVKfTqu0h/PUaEmhZ7gyDiioib5Wsh3oPAKhG+7+SWfU3roTDHaEWlJpkJjpXu+fQ==} - peerDependencies: - '@ai-sdk/anthropic': ^4.0.0 - '@ai-sdk/google': ^4.0.0 - '@ai-sdk/openai': ^4.0.0 - '@ai-sdk/provider': ^4.0.0 - ai: ^7.0.0 - peerDependenciesMeta: - '@ai-sdk/anthropic': - optional: true - '@ai-sdk/google': - optional: true - '@ai-sdk/openai': - optional: true - wrangler@4.112.0: resolution: {integrity: sha512-5H+XUD0TySCv1LuktFHDIEOkboH2nTfQs+35L+USt3MtntjDTMVIJprLgQcL2WBjulOyjxpd1vyTiSTJVW5MjQ==} engines: {node: '>=22.0.0'} @@ -2903,12 +2618,6 @@ snapshots: '@ai-sdk/provider-utils': 4.0.61(zod@4.3.6) zod: 4.3.6 - '@ai-sdk/anthropic@4.0.84(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 4.0.31 - '@ai-sdk/provider-utils': 5.0.64(zod@4.3.6) - zod: 4.3.6 - '@ai-sdk/gateway@3.0.128(zod@4.3.6)': dependencies: '@ai-sdk/provider': 3.0.10 @@ -2922,12 +2631,6 @@ snapshots: '@ai-sdk/provider-utils': 4.0.35(zod@4.3.6) zod: 4.3.6 - '@ai-sdk/openai@4.0.98(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 4.0.31 - '@ai-sdk/provider-utils': 5.0.64(zod@4.3.6) - zod: 4.3.6 - '@ai-sdk/provider-utils@4.0.28(zod@4.3.6)': dependencies: '@ai-sdk/provider': 3.0.10 @@ -2950,15 +2653,6 @@ snapshots: undici: 7.29.1 zod: 4.3.6 - '@ai-sdk/provider-utils@5.0.64(zod@4.3.6)': - dependencies: - '@ai-sdk/provider': 4.0.31 - '@standard-schema/spec': 1.1.0 - '@workflow/serde': 4.1.0 - eventsource-parser: 3.1.1 - undici: 7.29.1 - zod: 4.3.6 - '@ai-sdk/provider@3.0.10': dependencies: json-schema: 0.4.0 @@ -2971,10 +2665,6 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/provider@4.0.31': - dependencies: - json-schema: 0.4.0 - '@babel/code-frame@8.0.6': dependencies: '@babel/helper-validator-identifier': 8.0.6 @@ -3177,175 +2867,6 @@ snapshots: - supports-color - workflow - '@cloudflare/think@0.14.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 3.0.134(zod@4.3.6) - '@ai-sdk/openai': 3.0.80(zod@4.3.6) - '@cloudflare/codemode': 0.4.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 6.0.202(zod@4.3.6) - aywson: 0.0.16 - chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - create-think: 0.1.1 - just-bash: 3.6.0 - smol-toml: 1.9.0 - workers-ai-provider: 3.3.1(@ai-sdk/anthropic@3.0.134(zod@4.3.6))(@ai-sdk/openai@3.0.80(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) - yargs: 18.2.0 - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - vite: 7.3.5(yaml@2.9.1) - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - - '@cloudflare/think@0.15.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.98(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 6.0.202(zod@4.3.6) - aywson: 0.0.16 - chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - create-think: 0.1.1 - just-bash: 3.6.0 - smol-toml: 1.9.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) - yargs: 18.2.0 - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - vite: 7.3.5(yaml@2.9.1) - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - - '@cloudflare/think@0.15.1(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.98(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 6.0.202(zod@4.3.6) - aywson: 0.0.16 - chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - create-think: 0.1.1 - just-bash: 3.6.0 - smol-toml: 1.9.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) - yargs: 18.2.0 - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - vite: 7.3.5(yaml@2.9.1) - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - - '@cloudflare/think@0.16.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.98(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 6.0.202(zod@4.3.6) - chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - - '@cloudflare/think@0.17.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.98(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 6.0.202(zod@4.3.6) - chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - - '@cloudflare/think@0.18.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.98(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 6.0.202(zod@4.3.6) - chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - - '@cloudflare/think@0.19.0(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.98(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 6.0.202(zod@4.3.6) - chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)) - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - '@cloudflare/unenv-preset@2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260714.1)': dependencies: unenv: 2.0.0-rc.24 @@ -3917,8 +3438,6 @@ snapshots: '@vercel/oidc@3.2.0': {} - '@workflow/serde@4.1.0': {} - '@workflow/serde@4.1.0-beta.2': {} abort-controller@3.0.0: @@ -3962,64 +3481,6 @@ snapshots: - rolldown - supports-color - agents@0.18.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/workers-types@5.20261019.1)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): - dependencies: - '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) - '@cfworker/json-schema': 4.1.1 - '@cloudflare/codemode': 0.4.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) - '@rolldown/plugin-babel': 0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1)) - cron-schedule: 6.0.0 - esbuild: 0.28.2 - mimetext: 3.0.28 - nanoid: 5.1.16 - partyserver: 0.5.10(@cloudflare/workers-types@5.20261019.1) - partysocket: 1.3.0(react@19.3.1) - react: 19.3.1 - yaml: 2.9.1 - yargs: 18.2.0 - zod: 4.3.6 - optionalDependencies: - ai: 6.0.202(zod@4.3.6) - chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - vite: 7.3.5(yaml@2.9.1) - transitivePeerDependencies: - - '@babel/core' - - '@babel/plugin-transform-runtime' - - '@babel/runtime' - - '@cloudflare/workers-types' - - rolldown - - supports-color - - agents@0.22.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): - dependencies: - '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) - '@cfworker/json-schema': 4.1.1 - '@modelcontextprotocol/client': 2.0.0 - '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) - '@modelcontextprotocol/server': 2.0.0 - '@rolldown/plugin-babel': 0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1)) - cron-schedule: 6.0.0 - esbuild: 0.28.2 - mimetext: 3.0.28 - nanoid: 5.1.16 - partysocket: 1.3.0(react@19.3.1) - yaml: 2.9.1 - zod: 4.3.6 - optionalDependencies: - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - ai: 6.0.202(zod@4.3.6) - chat: 4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - react: 19.3.1 - vite: 7.3.5(yaml@2.9.1) - transitivePeerDependencies: - - '@babel/core' - - '@babel/plugin-transform-runtime' - - '@babel/runtime' - - rolldown - agents@0.28.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@6.0.202(zod@4.3.6))(chat@4.43.0(ai@6.0.202(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): dependencies: '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) @@ -5581,13 +5042,6 @@ snapshots: '@ai-sdk/anthropic': 3.0.134(zod@4.3.6) '@ai-sdk/openai': 3.0.80(zod@4.3.6) - workers-ai-provider@4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.98(zod@4.3.6))(ai@6.0.202(zod@4.3.6)): - dependencies: - ai: 6.0.202(zod@4.3.6) - optionalDependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.98(zod@4.3.6) - wrangler@4.112.0(@cloudflare/workers-types@5.20261019.1): dependencies: '@cloudflare/kv-asset-handler': 0.5.0 diff --git a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/package.json b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/package.json index a3ea66af5..d3ab98ba9 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/package.json +++ b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/package.json @@ -12,21 +12,9 @@ "vite": "7.3.5", "wrangler": "4.112.0", "zod": "4.3.6", - "cloudflare-think-v0-15": "npm:@cloudflare/think@0.15.0", - "cloudflare-think-v0-15-latest": "npm:@cloudflare/think@0.15.1", - "cloudflare-think-v0-16": "npm:@cloudflare/think@0.16.0", - "cloudflare-think-v0-16-latest": "npm:@cloudflare/think@0.16.0", - "cloudflare-think-v0-17": "npm:@cloudflare/think@0.17.0", - "cloudflare-think-v0-17-latest": "npm:@cloudflare/think@0.17.0", - "cloudflare-think-v0-18": "npm:@cloudflare/think@0.18.0", - "cloudflare-think-v0-18-latest": "npm:@cloudflare/think@0.18.0", - "cloudflare-think-v0-19": "npm:@cloudflare/think@0.19.0", - "cloudflare-think-v0-19-latest": "npm:@cloudflare/think@0.19.0", "cloudflare-think-v0-20": "npm:@cloudflare/think@0.20.0", "cloudflare-think-v0-20-latest": "npm:@cloudflare/think@0.20.2", - "cloudflare-think-v0-20-1": "npm:@cloudflare/think@0.20.1", - "agents-v0-18": "npm:agents@0.18.0", - "agents-v0-22": "npm:agents@0.22.0" + "cloudflare-think-v0-20-1": "npm:@cloudflare/think@0.20.1" }, "pnpm": { "overrides": { diff --git a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/pnpm-lock.yaml b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/pnpm-lock.yaml index cb92724aa..dce2247c5 100644 --- a/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/pnpm-lock.yaml +++ b/e2e/scenarios/cloudflare-think-instrumentation/versions/ai7/pnpm-lock.yaml @@ -39,48 +39,12 @@ importers: agents: specifier: 0.28.0 version: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - agents-v0-18: - specifier: npm:agents@0.18.0 - version: agents@0.18.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/workers-types@5.20261019.1)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - agents-v0-22: - specifier: npm:agents@0.22.0 - version: agents@0.22.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) ai: specifier: 7.0.138 version: 7.0.138(zod@4.3.6) ai-unwrapped: specifier: npm:ai@7.0.138 version: ai@7.0.138(zod@4.3.6) - cloudflare-think-v0-15: - specifier: npm:@cloudflare/think@0.15.0 - version: '@cloudflare/think@0.15.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' - cloudflare-think-v0-15-latest: - specifier: npm:@cloudflare/think@0.15.1 - version: '@cloudflare/think@0.15.1(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)' - cloudflare-think-v0-16: - specifier: npm:@cloudflare/think@0.16.0 - version: '@cloudflare/think@0.16.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-16-latest: - specifier: npm:@cloudflare/think@0.16.0 - version: '@cloudflare/think@0.16.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-17: - specifier: npm:@cloudflare/think@0.17.0 - version: '@cloudflare/think@0.17.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-17-latest: - specifier: npm:@cloudflare/think@0.17.0 - version: '@cloudflare/think@0.17.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-18: - specifier: npm:@cloudflare/think@0.18.0 - version: '@cloudflare/think@0.18.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-18-latest: - specifier: npm:@cloudflare/think@0.18.0 - version: '@cloudflare/think@0.18.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-19: - specifier: npm:@cloudflare/think@0.19.0 - version: '@cloudflare/think@0.19.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' - cloudflare-think-v0-19-latest: - specifier: npm:@cloudflare/think@0.19.0 - version: '@cloudflare/think@0.19.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' cloudflare-think-v0-20: specifier: npm:@cloudflare/think@0.20.0 version: '@cloudflare/think@0.20.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)' @@ -264,23 +228,6 @@ packages: resolution: {integrity: sha512-JRH40HwYIXdIiwSc/gNw65q5T/gaf691n4//2YOhjRE4YO9KzSFJ/N+RrTD3M8iGz2jI4Jg92wb6OAqfYsAkTQ==} engines: {node: '>=20'} - '@cloudflare/codemode@0.4.4': - resolution: {integrity: sha512-GL0IF7NiHwAC222riEYGX75NHcnhTornAPfRI0Mj3Ig7C1y9H89FL0xs+pdflIF74eecNkzynsA+JdCIkGvKeA==} - peerDependencies: - '@modelcontextprotocol/sdk': 1.31.0 - '@tanstack/ai': '>=0.8.0 <1.0.0' - ai: ^6.0.0 - zod: ^4.0.0 - peerDependenciesMeta: - '@modelcontextprotocol/sdk': - optional: true - '@tanstack/ai': - optional: true - ai: - optional: true - zod: - optional: true - '@cloudflare/codemode@0.5.4': resolution: {integrity: sha512-/iyoiYNKYai961R1m704hmLbzg280C7ut3zZ2GIgaA1VSQMetjUmsS2t9YPCuLu2TZ8bOSoUtEz9UmNS4QmbFQ==} peerDependencies: @@ -305,116 +252,6 @@ packages: '@cloudflare/shell@0.4.3': resolution: {integrity: sha512-6ZMKQZqdZeommh8LGFK5C2rep4byJfCuyjR4NBdMqn2wW9tbeDJORfDhP/No75MLx8nJeWdgeXvq3D2Ijpa0XA==} - '@cloudflare/think@0.15.0': - resolution: {integrity: sha512-vI7YhGRrxbsnMEA6gVWD7aaWxa9dZOJBFuc+d9DZVLD7jfasO1egJ6LbS7VS6kfjCBETIzudi+wlmS3wYISEYg==} - hasBin: true - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.18.0 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - vite: '>=6 <9' - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - vite: - optional: true - - '@cloudflare/think@0.15.1': - resolution: {integrity: sha512-BAMVRoBArhszewE0ONcq6sNxfB0QsXIZkhdZYl+6hXdUC/tHShRK1ZDaGhHuWhDBBGYsPY07ploFy4WOmCLkwQ==} - hasBin: true - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.18.0 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - vite: '>=6 <9' - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - vite: - optional: true - - '@cloudflare/think@0.16.0': - resolution: {integrity: sha512-SVUJR+ENNL/eu7L5fNZCYALd72DRJYSiu7efNyr6hzNwFXYZSZz0Ecz06DoPLfN6k+F5ABO+0CHLVLAfAtr7dA==} - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.20.2 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - - '@cloudflare/think@0.17.0': - resolution: {integrity: sha512-tnfMZSqSz1dhfBx0io/mXMJE2huwJc2kTPAkx55y1bTUQwt9A2uONBmN1FixNsI9DFp1zXJDzcO0juGFKfTyLQ==} - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.20.2 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - - '@cloudflare/think@0.18.0': - resolution: {integrity: sha512-eN3gZvO05UPucAaQ9GfIu5iKhMeRKqd+NzxfNdi3rhbAHhsTC3ckxPnXNlBmr8Pg0zcvaJK69KhWPv4AySeexQ==} - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.23.0 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - - '@cloudflare/think@0.19.0': - resolution: {integrity: sha512-7xYaVeQJA4Xnwuo2R5/zhbUjWftvKzVjdsZnOSYjo+BqJ+hbizemW8fCt1QTTP+TDixgXXiOQNlOmyNJXjTYUw==} - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@chat-adapter/telegram': ^4.29.0 - agents: '>=0.24.0 <1.0.0' - ai: ^6.0.0 || ^7.0.0 - react: ^19.0.0 - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@chat-adapter/telegram': - optional: true - react: - optional: true - '@cloudflare/think@0.20.0': resolution: {integrity: sha512-1+BMb0XhALPDmCbzbPhITITANrIqBBYCT0sEIHFSbGOwGhWKLmblzdw8YP/FySdXuYko+y5PIcCXoxjNz0Ji1g==} peerDependencies: @@ -1387,77 +1224,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - agents@0.18.0: - resolution: {integrity: sha512-ozQCDZrJerDMW/2/X3N+y6yzB4PAfiMtPN4jhK5fD+CFdYfc35k0mqNf/GTWzMA6Pc7WekOB/nFaAlIMrH9WvA==} - hasBin: true - peerDependencies: - '@ai-sdk/react': ^3.0.204 - '@tanstack/ai': '>=0.10.2 <1.0.0' - '@x402/core': ^2.0.0 - '@x402/evm': ^2.0.0 - ai: ^6.0.0 - chat: ^4.29.0 - just-bash: ^3.0.0 - react: ^19.0.0 - vite: '>=6.0.0 <9.0.0' - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@tanstack/ai': - optional: true - '@x402/core': - optional: true - '@x402/evm': - optional: true - ai: - optional: true - chat: - optional: true - just-bash: - optional: true - vite: - optional: true - - agents@0.22.0: - resolution: {integrity: sha512-dIy/BRdO5GSqdOIp0pmkcLmHCCxIKb4RBByXFXmXG6Nc6WBSNYRXoLLDvWj2fJAfi4l5/OndJjZuBAP0vW0DZQ==} - peerDependencies: - '@ai-sdk/react': ^3.0.0 || ^4.0.0 - '@cloudflare/codemode': '>=0.5.0' - '@modelcontextprotocol/client': 2.0.0 - '@modelcontextprotocol/sdk': 1.31.0 - '@modelcontextprotocol/server': 2.0.0 - '@tanstack/ai': '>=0.10.2 <1.0.0' - '@x402/core': ^2.0.0 - '@x402/evm': ^2.0.0 - ai: ^6.0.0 || ^7.0.0 - chat: ^4.29.0 - just-bash: ^3.0.0 - react: ^19.0.0 - vite: '>=6.0.0 <9.0.0' - zod: ^4.0.0 - peerDependenciesMeta: - '@ai-sdk/react': - optional: true - '@cloudflare/codemode': - optional: true - '@tanstack/ai': - optional: true - '@x402/core': - optional: true - '@x402/evm': - optional: true - ai: - optional: true - chat: - optional: true - just-bash: - optional: true - react: - optional: true - vite: - optional: true - agents@0.28.0: resolution: {integrity: sha512-5nYoykTqL6HWLwRyPP9XL4triRg+kkc6W1Ovt58lMz3oLbChRst6GWQVU3LvLgve8YIbo1SvQp0IR4TOrxAD6g==} hasBin: true @@ -1530,14 +1296,6 @@ packages: ajv@8.20.0: resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} - ansi-regex@6.4.0: - resolution: {integrity: sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==} - engines: {node: '>=12'} - - ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} - engines: {node: '>=12'} - anynum@1.0.1: resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==} @@ -1548,10 +1306,6 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - aywson@0.0.16: - resolution: {integrity: sha512-xLFICM6OgSMcysNHCgrhri7hpcn0TfuyU5KxtjpIAJAUuD0Bjph2pSkLgxjn45iQBjBxs4S5Fq+RmXhIYuQtNw==} - hasBin: true - bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -1609,10 +1363,6 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - chalk@5.6.2: - resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - character-entities@2.0.2: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} @@ -1637,10 +1387,6 @@ packages: clean-git-ref@2.0.1: resolution: {integrity: sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==} - cliui@9.0.1: - resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} - engines: {node: '>=20'} - commander@6.2.1: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} @@ -1684,10 +1430,6 @@ packages: engines: {node: '>=0.8'} hasBin: true - create-think@0.1.1: - resolution: {integrity: sha512-C8+k9fPArd1B0nnDUV83Fjw7hzJyaY+LN4v3Va+k4enMlSw0ZvyJERjJwntcp+1Snos+sy07SQYpV+1k10zARQ==} - hasBin: true - cron-schedule@6.0.0: resolution: {integrity: sha512-BoZaseYGXOo5j5HUwTaegIog3JJbuH4BbrY9A1ArLjXpy+RWb3mV28F/9Gv1dDA7E2L8kngWva4NWisnLTyfgQ==} engines: {node: '>=20'} @@ -1755,9 +1497,6 @@ packages: electron-to-chromium@1.5.460: resolution: {integrity: sha512-rRaVC7bNUyGsL+GMtmZfv3AfgG6za7gE9v5bT0PIbjEerddA0IQ+tCK05NFAXqCpNlrxBZqbFqquyxHRQONHTA==} - emoji-regex@10.6.0: - resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} - empathic@2.1.0: resolution: {integrity: sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==} engines: {node: '>=14'} @@ -1906,14 +1645,6 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-east-asian-width@1.7.0: - resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} - engines: {node: '>=18'} - get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -2049,9 +1780,6 @@ packages: engines: {node: '>=6'} hasBin: true - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - just-bash@3.6.0: resolution: {integrity: sha512-2COjEgcHdqKXeQSiNfPAHmpwQx4S8wATaIwog83g2t645U5tom6FED4CBBdr3M+0ioX4xZ26eODw3/nD6RQ6xw==} engines: {node: '>=20.19'} @@ -2310,11 +2038,6 @@ packages: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} - partyserver@0.5.10: - resolution: {integrity: sha512-t2B3mhTL1IOxCsj8rZgn4TxTuub7oLhypjc1/fGPNsbgnn9OsHms6uR3QEd5bFJ/7xrFo771j3DdUlll8cxgBg==} - peerDependencies: - '@cloudflare/workers-types': ^4.20260424.1 || ^5.20260703.1 - partysocket@1.3.0: resolution: {integrity: sha512-1zToNyolZFK/7nuAw/K2bZrNzFqaZyRoCEkS+9vG6WSC5ikrN6qWRe96q6ImU51uptz2r+dAwSkwhJVdQi4LiA==} peerDependencies: @@ -2545,21 +2268,9 @@ packages: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} - string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} - - string-width@8.3.0: - resolution: {integrity: sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==} - engines: {node: '>=20'} - string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - strip-ansi@7.2.0: - resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} - engines: {node: '>=12'} - strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -2757,10 +2468,6 @@ packages: '@cloudflare/workers-types': optional: true - wrap-ansi@9.0.2: - resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} - engines: {node: '>=18'} - wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -2780,23 +2487,11 @@ packages: resolution: {integrity: sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==} engines: {node: '>=16.0.0'} - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - yaml@2.9.1: resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} engines: {node: '>= 14.6'} hasBin: true - yargs-parser@22.0.0: - resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} - engines: {node: ^20.19.0 || ^22.12.0 || >=23} - - yargs@18.2.0: - resolution: {integrity: sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==} - engines: {node: ^20.19.0 || ^22.12.0 || >=23} - youch-core@0.3.3: resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} @@ -3006,15 +2701,6 @@ snapshots: '@chat-adapter/catalog@4.43.0': {} - '@cloudflare/codemode@0.4.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6)': - dependencies: - '@types/json-schema': 7.0.15 - acorn: 8.19.0 - optionalDependencies: - '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) - ai: 7.0.138(zod@4.3.6) - zod: 4.3.6 - '@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6)': dependencies: '@types/json-schema': 7.0.15 @@ -3036,148 +2722,6 @@ snapshots: - ai - zod - '@cloudflare/think@0.15.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.93(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 7.0.138(zod@4.3.6) - aywson: 0.0.16 - chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - create-think: 0.1.1 - just-bash: 3.6.0 - smol-toml: 1.9.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) - yargs: 18.2.0 - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - vite: 7.3.5(yaml@2.9.1) - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - - '@cloudflare/think@0.15.1(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.93(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 7.0.138(zod@4.3.6) - aywson: 0.0.16 - chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - create-think: 0.1.1 - just-bash: 3.6.0 - smol-toml: 1.9.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) - yargs: 18.2.0 - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - vite: 7.3.5(yaml@2.9.1) - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - - '@cloudflare/think@0.16.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.93(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 7.0.138(zod@4.3.6) - chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - - '@cloudflare/think@0.17.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.93(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 7.0.138(zod@4.3.6) - chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - - '@cloudflare/think@0.18.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.93(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 7.0.138(zod@4.3.6) - chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - - '@cloudflare/think@0.19.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': - dependencies: - '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) - '@ai-sdk/openai': 4.0.93(zod@4.3.6) - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - '@cloudflare/shell': 0.4.3(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - agents: 0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6) - ai: 7.0.138(zod@4.3.6) - chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - workers-ai-provider: 4.0.0(@ai-sdk/anthropic@4.0.84(zod@4.3.6))(@ai-sdk/openai@4.0.93(zod@4.3.6))(@ai-sdk/provider@4.0.31)(ai@7.0.138(zod@4.3.6)) - zod: 4.3.6 - optionalDependencies: - react: 19.3.1 - transitivePeerDependencies: - - '@ai-sdk/google' - - '@ai-sdk/provider' - - '@modelcontextprotocol/sdk' - - '@tanstack/ai' - - supports-color - - workflow - '@cloudflare/think@0.20.0(@ai-sdk/provider@4.0.31)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(react@19.3.1)(zod@4.3.6)': dependencies: '@ai-sdk/anthropic': 4.0.84(zod@4.3.6) @@ -3279,7 +2823,8 @@ snapshots: '@cloudflare/workerd-windows-64@1.20260714.1': optional: true - '@cloudflare/workers-types@5.20261019.1': {} + '@cloudflare/workers-types@5.20261019.1': + optional: true '@cspotcode/source-map-support@0.8.1': dependencies: @@ -3828,64 +3373,6 @@ snapshots: acorn@8.19.0: {} - agents@0.18.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/workers-types@5.20261019.1)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): - dependencies: - '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) - '@cfworker/json-schema': 4.1.1 - '@cloudflare/codemode': 0.4.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) - '@rolldown/plugin-babel': 0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1)) - cron-schedule: 6.0.0 - esbuild: 0.28.2 - mimetext: 3.0.28 - nanoid: 5.1.16 - partyserver: 0.5.10(@cloudflare/workers-types@5.20261019.1) - partysocket: 1.3.0(react@19.3.1) - react: 19.3.1 - yaml: 2.9.1 - yargs: 18.2.0 - zod: 4.3.6 - optionalDependencies: - ai: 7.0.138(zod@4.3.6) - chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - vite: 7.3.5(yaml@2.9.1) - transitivePeerDependencies: - - '@babel/core' - - '@babel/plugin-transform-runtime' - - '@babel/runtime' - - '@cloudflare/workers-types' - - rolldown - - supports-color - - agents@0.22.0(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): - dependencies: - '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) - '@cfworker/json-schema': 4.1.1 - '@modelcontextprotocol/client': 2.0.0 - '@modelcontextprotocol/sdk': 1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6) - '@modelcontextprotocol/server': 2.0.0 - '@rolldown/plugin-babel': 0.2.4(@babel/core@8.0.7)(@babel/runtime@7.29.10)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1)) - cron-schedule: 6.0.0 - esbuild: 0.28.2 - mimetext: 3.0.28 - nanoid: 5.1.16 - partysocket: 1.3.0(react@19.3.1) - yaml: 2.9.1 - zod: 4.3.6 - optionalDependencies: - '@cloudflare/codemode': 0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - ai: 7.0.138(zod@4.3.6) - chat: 4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6) - just-bash: 3.6.0 - react: 19.3.1 - vite: 7.3.5(yaml@2.9.1) - transitivePeerDependencies: - - '@babel/core' - - '@babel/plugin-transform-runtime' - - '@babel/runtime' - - rolldown - agents@0.28.0(@ai-sdk/provider@4.0.31)(@babel/core@8.0.7)(@babel/runtime@7.29.10)(@cloudflare/codemode@0.5.4(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(@modelcontextprotocol/client@2.0.0)(@modelcontextprotocol/sdk@1.31.0(@cfworker/json-schema@4.1.1)(zod@4.3.6))(@modelcontextprotocol/server@2.0.0)(ai@7.0.138(zod@4.3.6))(chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6))(just-bash@3.6.0)(react@19.3.1)(rolldown@1.2.14)(vite@7.3.5(yaml@2.9.1))(zod@4.3.6): dependencies: '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.7) @@ -3935,10 +3422,6 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - ansi-regex@6.4.0: {} - - ansi-styles@6.2.3: {} - anynum@1.0.1: {} async-lock@1.4.1: {} @@ -3947,11 +3430,6 @@ snapshots: dependencies: possible-typed-array-names: 1.1.0 - aywson@0.0.16: - dependencies: - chalk: 5.6.2 - jsonc-parser: 3.3.1 - bail@2.0.2: {} base64-js@1.5.1: {} @@ -4025,8 +3503,6 @@ snapshots: ccount@2.0.1: {} - chalk@5.6.2: {} - character-entities@2.0.2: {} chat@4.43.0(ai@7.0.138(zod@4.3.6))(zod@4.3.6): @@ -4050,12 +3526,6 @@ snapshots: clean-git-ref@2.0.1: {} - cliui@9.0.1: - dependencies: - string-width: 7.2.0 - strip-ansi: 7.2.0 - wrap-ansi: 9.0.2 - commander@6.2.1: {} content-disposition@2.0.1: {} @@ -4081,8 +3551,6 @@ snapshots: crc-32@1.2.2: {} - create-think@0.1.1: {} - cron-schedule@6.0.0: {} cross-spawn@7.0.6: @@ -4138,8 +3606,6 @@ snapshots: electron-to-chromium@1.5.460: {} - emoji-regex@10.6.0: {} - empathic@2.1.0: {} encodeurl@2.0.0: {} @@ -4345,10 +3811,6 @@ snapshots: gensync@1.0.0-beta.2: {} - get-caller-file@2.0.5: {} - - get-east-asian-width@1.7.0: {} - get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -4470,8 +3932,6 @@ snapshots: json5@2.2.3: {} - jsonc-parser@3.3.1: {} - just-bash@3.6.0: dependencies: diff: 8.0.4 @@ -4906,11 +4366,6 @@ snapshots: parseurl@1.3.3: {} - partyserver@0.5.10(@cloudflare/workers-types@5.20261019.1): - dependencies: - '@cloudflare/workers-types': 5.20261019.1 - nanoid: 5.1.16 - partysocket@1.3.0(react@19.3.1): dependencies: event-target-polyfill: 0.0.4 @@ -4998,7 +4453,8 @@ snapshots: re2js@1.3.3: {} - react@19.3.1: {} + react@19.3.1: + optional: true readable-stream@3.6.2: dependencies: @@ -5248,25 +4704,10 @@ snapshots: statuses@2.0.2: {} - string-width@7.2.0: - dependencies: - emoji-regex: 10.6.0 - get-east-asian-width: 1.7.0 - strip-ansi: 7.2.0 - - string-width@8.3.0: - dependencies: - get-east-asian-width: 1.7.0 - strip-ansi: 7.2.0 - string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 - strip-ansi@7.2.0: - dependencies: - ansi-regex: 6.4.0 - strip-json-comments@2.0.1: optional: true @@ -5466,33 +4907,14 @@ snapshots: - bufferutil - utf-8-validate - wrap-ansi@9.0.2: - dependencies: - ansi-styles: 6.2.3 - string-width: 7.2.0 - strip-ansi: 7.2.0 - wrappy@1.0.2: {} ws@8.21.0: {} xml-naming@0.3.0: {} - y18n@5.0.8: {} - yaml@2.9.1: {} - yargs-parser@22.0.0: {} - - yargs@18.2.0: - dependencies: - cliui: 9.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - string-width: 8.3.0 - y18n: 5.0.8 - yargs-parser: 22.0.0 - youch-core@0.3.3: dependencies: '@poppinss/exception': 1.2.3 diff --git a/e2e/scripts/cassette-audit.mjs b/e2e/scripts/cassette-audit.mjs new file mode 100644 index 000000000..77285ddc8 --- /dev/null +++ b/e2e/scripts/cassette-audit.mjs @@ -0,0 +1,129 @@ +import { lstat, readFile, readdir } from "node:fs/promises"; +import path from "node:path"; + +// The caller must run the tests in a fresh context directory and only invoke +// this after Vitest exits successfully. The report additionally protects +// scenarios with skipped tests or test files omitted from the run. +export async function auditCassettes({ + e2eDir, + runContextDir, + reportPath, + clean = false, +}) { + const report = JSON.parse(await readFile(reportPath, "utf8")); + if ( + report.success !== true || + report.numFailedTests !== 0 || + report.numFailedTestSuites !== 0 || + !Array.isArray(report.testResults) + ) { + throw new Error( + "Cassette audit requires a successful, complete test report.", + ); + } + const resultsByFile = new Map( + report.testResults.map((result) => [ + path.resolve(e2eDir, result.name), + result, + ]), + ); + const variantsByScenario = new Map(); + for (const entry of await readdir(runContextDir)) { + if (!/^run-context-.*\.ndjson$/.test(entry)) continue; + for (const line of ( + await readFile(path.join(runContextDir, entry), "utf8") + ).split("\n")) { + if (!line.trim()) continue; + const record = JSON.parse(line); + if ( + !/^[a-z0-9][a-z0-9-]*$/.test(record.scenarioDirName ?? "") || + (record.cassetteVariantKey !== null && + typeof record.cassetteVariantKey !== "string") + ) { + throw new Error(`Invalid cassette usage record in ${entry}.`); + } + const variants = + variantsByScenario.get(record.scenarioDirName) ?? new Set(); + if (record.cassetteVariantKey !== null) { + variants.add(record.cassetteVariantKey); + } + variantsByScenario.set(record.scenarioDirName, variants); + } + } + + const unused = []; + const skipped = []; + const scenariosDir = path.join(e2eDir, "scenarios"); + for (const scenario of await readdir(scenariosDir, { withFileTypes: true })) { + if (!scenario.isDirectory()) continue; + const scenarioDir = path.join(scenariosDir, scenario.name); + const cassetteDir = path.join(scenarioDir, "__cassettes__"); + let stat; + try { + stat = await lstat(cassetteDir); + } catch (error) { + if (error.code === "ENOENT") continue; + throw error; + } + if (!stat.isDirectory()) continue; + const artifacts = new Set(); + for (const entry of await readdir(cassetteDir, { withFileTypes: true })) { + if (entry.isFile() && entry.name.endsWith(".cassette.json")) { + artifacts.add(entry.name.slice(0, -".cassette.json".length)); + } else if ( + entry.isDirectory() && + entry.name.endsWith(".cassette.blobs") + ) { + artifacts.add(entry.name.slice(0, -".cassette.blobs".length)); + } + } + if (artifacts.size === 0) continue; + const testFiles = (await readdir(scenarioDir)) + .filter((name) => name.endsWith(".test.ts")) + .map((name) => path.join(scenarioDir, name)); + // An unselected scenario is outside the scope of this audit. + if (!testFiles.some((file) => resultsByFile.has(file))) continue; + const variants = variantsByScenario.get(scenario.name); + if ( + !variants || + testFiles.some((file) => { + const result = resultsByFile.get(file); + return ( + result?.status !== "passed" || + !result.assertionResults?.length || + result.assertionResults.some((test) => test.status !== "passed") + ); + }) + ) { + skipped.push(scenario.name); + continue; + } + for (const variantKey of [...artifacts].sort()) { + if (!variants.has(variantKey)) { + unused.push({ scenarioName: scenario.name, cassetteDir, variantKey }); + } + } + } + + // Finish validating the entire input before deleting any artifacts. + if (clean) { + const { createJsonFileStore } = await import("@braintrust/seinfeld"); + for (const { cassetteDir, variantKey } of unused) { + await createJsonFileStore({ rootDir: cassetteDir }).delete(variantKey); + } + } + for (const { scenarioName, variantKey } of unused) { + console.error( + `[cassettes] ${clean ? "Removed" : "Unused"}: ${scenarioName}/${variantKey}`, + ); + } + for (const scenarioName of skipped) { + console.error( + `[cassettes] Not checked: ${scenarioName} (incomplete test or usage coverage).`, + ); + } + console.error( + `[cassettes] ${unused.length} unused cassette variant(s)${clean ? " removed" : ""}.`, + ); + return { unused, skipped }; +} diff --git a/e2e/scripts/run-e2e-tests.mjs b/e2e/scripts/run-e2e-tests.mjs index 9d5841023..3c5990de5 100644 --- a/e2e/scripts/run-e2e-tests.mjs +++ b/e2e/scripts/run-e2e-tests.mjs @@ -2,9 +2,10 @@ import { spawn } from "node:child_process"; import { existsSync } from "node:fs"; -import { readdir } from "node:fs/promises"; +import { mkdir, mkdtemp, readdir, rm } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { auditCassettes } from "./cassette-audit.mjs"; const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url)); const E2E_DIR = path.resolve(SCRIPT_DIR, ".."); @@ -18,6 +19,8 @@ const DEFAULT_OPENAI_CODEX_E2E_MODEL = "gpt-5.3-codex"; const rawArgs = process.argv.slice(2).filter((arg) => arg !== "--"); const updateSnapshots = rawArgs.includes("--update"); +const cleanCassettes = rawArgs.includes("--clean-cassettes"); +const checkCassettes = cleanCassettes || rawArgs.includes("--check-cassettes"); const shardArgIndex = rawArgs.findIndex( (arg) => arg === "--shard" || arg.startsWith("--shard="), ); @@ -36,9 +39,34 @@ const shardArgs = shardValue ? [`--shard=${shardValue}`] : []; const scenarioArgs = rawArgs.filter( (arg, index) => arg !== "--update" && + arg !== "--check-cassettes" && + arg !== "--clean-cassettes" && index !== shardArgIndex && !(shardArg === "--shard" && index === shardArgIndex + 1), ); +if ( + checkCassettes && + (shardValue || + updateSnapshots || + scenarioArgs.some( + (name) => + !/^[a-z0-9][a-z0-9-]*$/.test(name) || + !existsSync(path.join(E2E_DIR, "scenarios", name, "scenario.test.ts")), + )) +) { + console.error( + "[cassettes] Select whole scenarios by name; filters, sharding, and snapshot updates are not supported.", + ); + process.exit(1); +} +const contextParent = process.env.BRAINTRUST_E2E_RUN_CONTEXT_DIR; +let auditDir; +if (checkCassettes) { + const parent = contextParent || path.join(E2E_DIR, ".bt-tmp"); + await mkdir(parent, { recursive: true }); + auditDir = await mkdtemp(path.join(parent, "cassette-audit-")); +} +const reportPath = auditDir && path.join(auditDir, "results.json"); const testTargets = scenarioArgs.length > 0 ? scenarioArgs.map((arg) => scenarioPathArg(arg)) @@ -49,17 +77,41 @@ const vitestArgs = [ ...testTargets, ...shardArgs, ...(updateSnapshots ? ["--update"] : []), + ...(checkCassettes + ? ["--reporter=default", "--reporter=json", `--outputFile=${reportPath}`] + : []), ]; -const result = await runProcess(VITEST_COMMAND, vitestArgs, { - cwd: E2E_DIR, - env: replayEnv(), -}); - -if (result.signal) { - console.error(`[e2e] Vitest exited after receiving ${result.signal}.`); - process.exit(1); +let exitCode; +try { + const result = await runProcess(VITEST_COMMAND, vitestArgs, { + cwd: E2E_DIR, + env: { + ...replayEnv(), + ...(auditDir ? { BRAINTRUST_E2E_RUN_CONTEXT_DIR: auditDir } : {}), + }, + }); + exitCode = result.code ?? 1; + if (result.signal) { + console.error(`[e2e] Vitest exited after receiving ${result.signal}.`); + exitCode = 1; + } else if (result.code === 0 && checkCassettes) { + const { unused, skipped } = await auditCassettes({ + e2eDir: E2E_DIR, + runContextDir: auditDir, + reportPath, + clean: cleanCassettes, + }); + if ((!cleanCassettes && unused.length > 0) || skipped.length > 0) { + exitCode = 1; + } + } +} finally { + // Preserve explicitly requested trace records for the e2e summary. + if (auditDir && !contextParent) { + await rm(auditDir, { recursive: true, force: true }); + } } -process.exit(result.code ?? 1); +process.exit(exitCode); function scenarioPathArg(arg) { if (!/^[a-z0-9][a-z0-9-]*$/.test(arg)) { diff --git a/e2e/scripts/run-record-tests.mjs b/e2e/scripts/run-record-tests.mjs index 15f6d536b..3a752c6b3 100644 --- a/e2e/scripts/run-record-tests.mjs +++ b/e2e/scripts/run-record-tests.mjs @@ -2,9 +2,10 @@ import { spawn } from "node:child_process"; import { existsSync } from "node:fs"; -import { mkdir, mkdtemp, readFile, readdir, rm } from "node:fs/promises"; +import { mkdir, mkdtemp, readdir, rm } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { auditCassettes } from "./cassette-audit.mjs"; const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url)); const E2E_DIR = path.resolve(SCRIPT_DIR, ".."); @@ -55,20 +56,27 @@ if (shouldBuildDeps) { } } -await mkdir(TMP_ROOT, { recursive: true }); -const runContextDir = await mkdtemp(path.join(TMP_ROOT, "record-context-")); +const contextParent = process.env[RUN_CONTEXT_DIR_ENV]; +await mkdir(contextParent || TMP_ROOT, { recursive: true }); +const runContextDir = await mkdtemp( + path.join(contextParent || TMP_ROOT, "record-context-"), +); const result = await runVitest(scenarioNames, runContextDir); try { if (result.code === 0) { - await cleanupStaleCassettes( - scenarioNames, - await readRunContextRecords(runContextDir), - ); + await auditCassettes({ + e2eDir: E2E_DIR, + runContextDir, + reportPath: path.join(runContextDir, "results.json"), + clean: true, + }); } } finally { - await rm(runContextDir, { recursive: true, force: true }); + if (!contextParent) { + await rm(runContextDir, { recursive: true, force: true }); + } } if (result.signal) { @@ -81,123 +89,6 @@ function scenarioTestPath(scenarioName) { return path.join(E2E_DIR, "scenarios", scenarioName, "scenario.test.ts"); } -async function readRunContextRecords(dir) { - let entries; - try { - entries = await readdir(dir, { withFileTypes: true }); - } catch (err) { - if (err.code === "ENOENT") { - return []; - } - throw err; - } - - const records = []; - for (const entry of entries) { - if ( - !entry.isFile() || - !entry.name.startsWith("run-context-") || - !entry.name.endsWith(".ndjson") - ) { - continue; - } - - const raw = await readFile(path.join(dir, entry.name), "utf8"); - for (const line of raw.split("\n")) { - if (!line.trim()) { - continue; - } - try { - const record = JSON.parse(line); - if (record && typeof record === "object") { - records.push(record); - } - } catch { - console.error( - `[record] Ignoring malformed run-context line in ${entry.name}.`, - ); - } - } - } - return records; -} - -async function cleanupStaleCassettes(scenarioNames, records) { - const { createJsonFileStore } = await import("@braintrust/seinfeld"); - const variantsByScenario = new Map(); - for (const record of records) { - if ( - typeof record.scenarioDirName !== "string" || - typeof record.variantKey !== "string" || - !record.variantKey.trim() - ) { - continue; - } - - const variants = - variantsByScenario.get(record.scenarioDirName) ?? new Set(); - variants.add(record.variantKey); - variantsByScenario.set(record.scenarioDirName, variants); - } - - const cleanupScenarioNames = - scenarioNames.length > 0 ? scenarioNames : [...variantsByScenario.keys()]; - - for (const scenarioName of cleanupScenarioNames) { - const cassetteDir = path.join( - E2E_DIR, - "scenarios", - scenarioName, - "__cassettes__", - ); - const variantsToKeep = variantsByScenario.get(scenarioName); - if (!variantsToKeep || variantsToKeep.size === 0) { - continue; - } - - const variantKeys = await cassetteArtifactVariantKeys(cassetteDir); - const store = createJsonFileStore({ rootDir: cassetteDir }); - - let removedCount = 0; - for (const variantKey of variantKeys) { - if (variantsToKeep.has(variantKey)) { - continue; - } - - await store.delete(variantKey); - removedCount++; - } - - if (removedCount > 0) { - console.error( - `[record] Removed ${removedCount} stale cassette artifact(s) in ${scenarioName}.`, - ); - } - } -} - -async function cassetteArtifactVariantKeys(cassetteDir) { - let entries; - try { - entries = await readdir(cassetteDir, { withFileTypes: true }); - } catch (err) { - if (err.code === "ENOENT") { - return []; - } - throw err; - } - - const variantKeys = new Set(); - for (const entry of entries) { - if (entry.isFile() && entry.name.endsWith(".cassette.json")) { - variantKeys.add(entry.name.slice(0, -".cassette.json".length)); - } else if (entry.isDirectory() && entry.name.endsWith(".cassette.blobs")) { - variantKeys.add(entry.name.slice(0, -".cassette.blobs".length)); - } - } - return [...variantKeys].sort(); -} - async function runVitest(scenarioNames, runContextDir) { const env = { ...process.env, @@ -219,6 +110,11 @@ async function runVitest(scenarioNames, runContextDir) { ...(await defaultScenarioTestPaths()), "--update", ]; + vitestArgs.push( + "--reporter=default", + "--reporter=json", + `--outputFile=${path.join(runContextDir, "results.json")}`, + ); return await runProcess(VITEST_COMMAND, vitestArgs, { cwd: E2E_DIR, diff --git a/package.json b/package.json index e336f923f..54b4a3f8c 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "lint": "turbo run lint", "fix:formatting": "prettier --write .", "fix:lint": "turbo run fix:lint", - "yalc:publish": "turbo run yalc:publish" + "yalc:publish": "turbo run yalc:publish", + "test:e2e:cassettes": "turbo run test:e2e -- --check-cassettes" }, "engines": { "pnpm": ">=10.27.0",